<xi:include href="xml/gtklevelbar.xml" />
<xi:include href="xml/gtkstatusbar.xml" />
<xi:include href="xml/gtkaccellabel.xml" />
- <xi:include href="xml/gtkstatusicon.xml" />
</chapter>
<chapter id="ButtonWidgets">
<xi:include href="xml/gtkiconfactory.xml" />
<xi:include href="xml/gtknumerableicon.xml" />
<xi:include href="xml/gtkarrow.xml" />
+ <xi:include href="xml/gtkstatusicon.xml" />
</chapter>
</part>
deprecated/gtkradioaction.h \
deprecated/gtkrc.h \
deprecated/gtkrecentaction.h \
+ deprecated/gtkstatusicon.h \
deprecated/gtkstock.h \
deprecated/gtkstyle.h \
deprecated/gtksymboliccolor.h \
deprecated/gtktable.h \
deprecated/gtktearoffmenuitem.h \
deprecated/gtktoggleaction.h \
- deprecated/gtkuimanager.h \
+ deprecated/gtkuimanager.h \
deprecated/gtkvbbox.h \
deprecated/gtkvbox.h \
deprecated/gtkvscale.h \
gtkstack.h \
gtkstackswitcher.h \
gtkstatusbar.h \
- gtkstatusicon.h \
gtkstylecontext.h \
gtkstyleproperties.h \
gtkstyleprovider.h \
deprecated/gtkradioaction.c \
deprecated/gtkrc.c \
deprecated/gtkrecentaction.c \
+ deprecated/gtkstatusicon.c \
deprecated/gtkstock.c \
deprecated/gtkstyle.c \
deprecated/gtksymboliccolor.c \
gtkstack.c \
gtkstackswitcher.c \
gtkstatusbar.c \
- gtkstatusicon.c \
gtkstyleanimation.c \
gtkstylecascade.c \
gtkstylecontext.c \
gtkplug.c \
gtksocket.c \
gtkxembed.c \
- gtktrayicon-x11.c \
+ deprecated/gtktrayicon-x11.c \
gtkapplication-x11.c \
gtkmountoperation-x11.c
gtk_all_c_sources += $(gtk_use_x11_c_sources) $(gtk_use_win32_c_sources) $(gtk_use_quartz_c_sources) $(gtk_use_stub_c_sources)
gtk_use_x11_private_h_sources = \
gtkxembed.h \
- gtktrayicon.h \
+ deprecated/gtktrayicon.h \
xembed.h
if USE_X11
gtk_c_sources += $(gtk_use_x11_c_sources)
paper_names.c \
paper_names_offsets.c \
gen-paper-names.c \
- gtkstatusicon-quartz.c \
+ deprecated/gtkstatusicon-quartz.c \
gtkversion.h.in \
gtkmarshalers.list \
fallback-c89.c
--- /dev/null
+/* gtkstatusicon-quartz.c:
+ *
+ * Copyright (C) 2006 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * GCC on Mac OS X handles inlined objective C in C-files.
+ *
+ * Authors:
+ * Mikael Hallendal <micke@imendio.com>
+ */
+
+#import <Cocoa/Cocoa.h>
+#include <quartz/gdkquartz.h>
+
+#define QUARTZ_POOL_ALLOC NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]
+#define QUARTZ_POOL_RELEASE [pool release]
+
+@interface GtkQuartzStatusIcon : NSObject
+{
+ GtkStatusIcon *status_icon;
+ NSStatusBar *ns_bar;
+ NSStatusItem *ns_item;
+ NSImage *current_image;
+ NSString *ns_tooltip;
+}
+- (id) initWithStatusIcon:(GtkStatusIcon *)status_icon;
+- (void) ensureItem;
+- (void) actionCb:(NSObject *)button;
+- (void) setImage:(GdkPixbuf *)pixbuf;
+- (void) setVisible:(gboolean)visible;
+- (void) setToolTip:(const gchar *)tooltip_text;
+- (float) getWidth;
+- (float) getHeight;
+@end
+
+@implementation GtkQuartzStatusIcon : NSObject
+- (id) initWithStatusIcon:(GtkStatusIcon *)icon
+{
+ [super init];
+ status_icon = icon;
+ ns_bar = [NSStatusBar systemStatusBar];
+
+ return self;
+}
+
+- (void) ensureItem
+{
+ if (ns_item != nil)
+ return;
+
+ ns_item = [ns_bar statusItemWithLength:NSVariableStatusItemLength];
+ [ns_item setAction:@selector(actionCb:)];
+ [ns_item setTarget:self];
+ [ns_item retain];
+}
+
+- (void) dealloc
+{
+ g_print ("Deallocating GtkQuartzStatusIcon\n");
+ [current_image release];
+ [ns_item release];
+ [ns_bar release];
+
+ [super dealloc];
+}
+
+- (void) actionCb:(NSObject *)button
+{
+ NSEvent *event = [NSApp currentEvent];
+ double time = [event timestamp];
+
+ g_signal_emit (status_icon,
+ status_icon_signals [POPUP_MENU_SIGNAL], 0,
+ 1,
+ time * 1000.0);
+}
+
+- (void) setImage:(GdkPixbuf *)pixbuf
+{
+ /* Support NULL */
+ [self ensureItem];
+
+ if (current_image != nil) {
+ [current_image release];
+ current_image = nil;
+ }
+
+ if (!pixbuf) {
+ [ns_item release];
+ ns_item = nil;
+ return;
+ }
+
+ current_image = gdk_quartz_pixbuf_to_ns_image_libgtk_only (pixbuf);
+ [current_image retain];
+
+ [ns_item setImage:current_image];
+}
+
+- (void) setVisible:(gboolean)visible
+{
+ if (visible) {
+ [self ensureItem];
+ if (ns_item != nil)
+ [ns_item setImage:current_image];
+ if (ns_tooltip != nil)
+ [ns_item setToolTip:ns_tooltip];
+ } else {
+ [ns_item release];
+ ns_item = nil;
+ }
+}
+
+- (void) setToolTip:(const gchar *)tooltip_text
+{
+ [ns_tooltip release];
+ ns_tooltip = [[NSString stringWithUTF8String:tooltip_text] retain];
+
+ [ns_item setToolTip:ns_tooltip];
+}
+
+- (float) getWidth
+{
+ return [ns_bar thickness];
+}
+
+- (float) getHeight
+{
+ return [ns_bar thickness];
+}
+@end
+
+
+
--- /dev/null
+/* gtkstatusicon.c:
+ *
+ * Copyright (C) 2003 Sun Microsystems, Inc.
+ * Copyright (C) 2005 Hans Breuer <hans@breuer.org>
+ * Copyright (C) 2005 Novell, Inc.
+ * Copyright (C) 2006 Imendio AB
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Mark McLoughlin <mark@skynet.ie>
+ * Hans Breuer <hans@breuer.org>
+ * Tor Lillqvist <tml@novell.com>
+ * Mikael Hallendal <micke@imendio.com>
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#define GDK_DISABLE_DEPRECATION_WARNINGS
+#include "gtkstatusicon.h"
+
+#include "gtkintl.h"
+#include "gtkiconhelperprivate.h"
+#include "gtkmain.h"
+#include "gtkmarshalers.h"
+#include "gtksizerequest.h"
+#include "gtkprivate.h"
+#include "gtkwidget.h"
+#include "gtktooltip.h"
+#include "gtkicontheme.h"
+#include "gtklabel.h"
+#include "gtktypebuiltins.h"
+
+#ifdef GDK_WINDOWING_X11
+#include "gdk/x11/gdkx.h"
+#include "gtktrayicon.h"
+#endif
+
+#ifdef GDK_WINDOWING_WIN32
+#include "gdk/win32/gdkwin32.h"
+#define WM_GTK_TRAY_NOTIFICATION (WM_USER+1)
+#endif
+
+
+/**
+ * SECTION:gtkstatusicon
+ * @Short_description: Display an icon in the system tray
+ * @Title: GtkStatusIcon
+ *
+ * The “system tray” or notification area is normally used for transient icons
+ * that indicate some special state. For example, a system tray icon might
+ * appear to tell the user that they have new mail, or have an incoming instant
+ * message, or something along those lines. The basic idea is that creating an
+ * icon in the notification area is less annoying than popping up a dialog.
+ *
+ * A #GtkStatusIcon object can be used to display an icon in a “system tray”.
+ * The icon can have a tooltip, and the user can interact with it by
+ * activating it or popping up a context menu. Critical information should
+ * not solely be displayed in a #GtkStatusIcon, since it may not be
+ * visible (e.g. when the user doesn’t have a notification area on his panel).
+ * This can be checked with gtk_status_icon_is_embedded().
+ *
+ * On X11, the implementation follows the
+ * [FreeDesktop System Tray Specification](http://www.freedesktop.org/wiki/Specifications/systemtray-spec).
+ * Implementations of the “tray” side of this specification can
+ * be found e.g. in the GNOME 2 and KDE panel applications.
+ *
+ * Note that a GtkStatusIcon is not a widget, but just
+ * a #GObject. Making it a widget would be impractical, since the system tray
+ * on Win32 doesn’t allow to embed arbitrary widgets.
+ *
+ * GtkStatusIcon has been deprecated in 3.16. You should consider using
+ * notifications or more modern platform-specific APIs instead.
+ */
+
+
+#define BLINK_TIMEOUT 500
+
+enum
+{
+ PROP_0,
+ PROP_PIXBUF,
+ PROP_FILE,
+ PROP_STOCK,
+ PROP_ICON_NAME,
+ PROP_GICON,
+ PROP_STORAGE_TYPE,
+ PROP_SIZE,
+ PROP_SCREEN,
+ PROP_VISIBLE,
+ PROP_ORIENTATION,
+ PROP_EMBEDDED,
+ PROP_BLINKING,
+ PROP_HAS_TOOLTIP,
+ PROP_TOOLTIP_TEXT,
+ PROP_TOOLTIP_MARKUP,
+ PROP_TITLE
+};
+
+enum
+{
+ ACTIVATE_SIGNAL,
+ POPUP_MENU_SIGNAL,
+ SIZE_CHANGED_SIGNAL,
+ BUTTON_PRESS_EVENT_SIGNAL,
+ BUTTON_RELEASE_EVENT_SIGNAL,
+ SCROLL_EVENT_SIGNAL,
+ QUERY_TOOLTIP_SIGNAL,
+ LAST_SIGNAL
+};
+
+static guint status_icon_signals [LAST_SIGNAL] = { 0 };
+
+#ifdef GDK_WINDOWING_QUARTZ
+#include "gtkstatusicon-quartz.c"
+#endif
+
+struct _GtkStatusIconPrivate
+{
+#ifdef GDK_WINDOWING_X11
+ GtkWidget *tray_icon;
+ GtkWidget *image;
+#else
+ GtkWidget *dummy_widget;
+#endif
+
+#ifdef GDK_WINDOWING_WIN32
+ NOTIFYICONDATAW nid;
+ gint taskbar_top;
+ gint last_click_x, last_click_y;
+ GtkOrientation orientation;
+ gchar *tooltip_text;
+ gchar *title;
+#endif
+
+#ifdef GDK_WINDOWING_QUARTZ
+ GtkQuartzStatusIcon *status_item;
+ gchar *tooltip_text;
+ gchar *title;
+#endif
+
+ gint size;
+ GtkIconHelper *icon_helper;
+ guint visible : 1;
+};
+
+static void gtk_status_icon_constructed (GObject *object);
+static void gtk_status_icon_finalize (GObject *object);
+static void gtk_status_icon_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void gtk_status_icon_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+#ifdef GDK_WINDOWING_X11
+static void gtk_status_icon_size_allocate (GtkStatusIcon *status_icon,
+ GtkAllocation *allocation);
+static void gtk_status_icon_screen_changed (GtkStatusIcon *status_icon,
+ GdkScreen *old_screen);
+static void gtk_status_icon_embedded_changed (GtkStatusIcon *status_icon);
+static void gtk_status_icon_orientation_changed (GtkStatusIcon *status_icon);
+static void gtk_status_icon_padding_changed (GtkStatusIcon *status_icon);
+static void gtk_status_icon_icon_size_changed(GtkStatusIcon *status_icon);
+static void gtk_status_icon_fg_changed (GtkStatusIcon *status_icon);
+static void gtk_status_icon_color_changed (GtkTrayIcon *tray,
+ GParamSpec *pspec,
+ GtkStatusIcon *status_icon);
+static gboolean gtk_status_icon_scroll (GtkStatusIcon *status_icon,
+ GdkEventScroll *event);
+static gboolean gtk_status_icon_query_tooltip (GtkStatusIcon *status_icon,
+ gint x,
+ gint y,
+ gboolean keyboard_tip,
+ GtkTooltip *tooltip);
+
+static gboolean gtk_status_icon_key_press (GtkStatusIcon *status_icon,
+ GdkEventKey *event);
+static void gtk_status_icon_popup_menu (GtkStatusIcon *status_icon);
+#endif
+static gboolean gtk_status_icon_button_press (GtkStatusIcon *status_icon,
+ GdkEventButton *event);
+static gboolean gtk_status_icon_button_release (GtkStatusIcon *status_icon,
+ GdkEventButton *event);
+static void gtk_status_icon_reset_image_data (GtkStatusIcon *status_icon);
+static void gtk_status_icon_update_image (GtkStatusIcon *status_icon);
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkStatusIcon, gtk_status_icon, G_TYPE_OBJECT)
+
+static void
+gtk_status_icon_class_init (GtkStatusIconClass *class)
+{
+ GObjectClass *gobject_class = (GObjectClass *) class;
+
+ gobject_class->constructed = gtk_status_icon_constructed;
+ gobject_class->finalize = gtk_status_icon_finalize;
+ gobject_class->set_property = gtk_status_icon_set_property;
+ gobject_class->get_property = gtk_status_icon_get_property;
+
+ class->button_press_event = NULL;
+ class->button_release_event = NULL;
+ class->scroll_event = NULL;
+ class->query_tooltip = NULL;
+
+ g_object_class_install_property (gobject_class,
+ PROP_PIXBUF,
+ g_param_spec_object ("pixbuf",
+ P_("Pixbuf"),
+ P_("A GdkPixbuf to display"),
+ GDK_TYPE_PIXBUF,
+ GTK_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_FILE,
+ g_param_spec_string ("file",
+ P_("Filename"),
+ P_("Filename to load and display"),
+ NULL,
+ GTK_PARAM_WRITABLE));
+
+ /**
+ * GtkStatusIcon:stock:
+ *
+ * Deprecated: 3.10: Use #GtkStatusIcon:icon-name instead.
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_STOCK,
+ g_param_spec_string ("stock",
+ P_("Stock ID"),
+ P_("Stock ID for a stock image to display"),
+ NULL,
+ GTK_PARAM_READWRITE | G_PARAM_DEPRECATED));
+
+ g_object_class_install_property (gobject_class,
+ PROP_ICON_NAME,
+ g_param_spec_string ("icon-name",
+ P_("Icon Name"),
+ P_("The name of the icon from the icon theme"),
+ NULL,
+ GTK_PARAM_READWRITE));
+
+ /**
+ * GtkStatusIcon:gicon:
+ *
+ * The #GIcon displayed in the #GtkStatusIcon. For themed icons,
+ * the image will be updated automatically if the theme changes.
+ *
+ * Since: 2.14
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_GICON,
+ g_param_spec_object ("gicon",
+ P_("GIcon"),
+ P_("The GIcon being displayed"),
+ G_TYPE_ICON,
+ GTK_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_STORAGE_TYPE,
+ g_param_spec_enum ("storage-type",
+ P_("Storage type"),
+ P_("The representation being used for image data"),
+ GTK_TYPE_IMAGE_TYPE,
+ GTK_IMAGE_EMPTY,
+ GTK_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_SIZE,
+ g_param_spec_int ("size",
+ P_("Size"),
+ P_("The size of the icon"),
+ 0,
+ G_MAXINT,
+ 0,
+ GTK_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_SCREEN,
+ g_param_spec_object ("screen",
+ P_("Screen"),
+ P_("The screen where this status icon will be displayed"),
+ GDK_TYPE_SCREEN,
+ GTK_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_VISIBLE,
+ g_param_spec_boolean ("visible",
+ P_("Visible"),
+ P_("Whether the status icon is visible"),
+ TRUE,
+ GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
+
+
+ /**
+ * GtkStatusIcon:embedded:
+ *
+ * %TRUE if the statusicon is embedded in a notification area.
+ *
+ * Since: 2.12
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_EMBEDDED,
+ g_param_spec_boolean ("embedded",
+ P_("Embedded"),
+ P_("Whether the status icon is embedded"),
+ FALSE,
+ GTK_PARAM_READABLE));
+
+ /**
+ * GtkStatusIcon:orientation:
+ *
+ * The orientation of the tray in which the statusicon
+ * is embedded.
+ *
+ * Since: 2.12
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_ORIENTATION,
+ g_param_spec_enum ("orientation",
+ P_("Orientation"),
+ P_("The orientation of the tray"),
+ GTK_TYPE_ORIENTATION,
+ GTK_ORIENTATION_HORIZONTAL,
+ GTK_PARAM_READABLE));
+
+/**
+ * GtkStatusIcon:has-tooltip:
+ *
+ * Enables or disables the emission of #GtkStatusIcon::query-tooltip on
+ * @status_icon. A value of %TRUE indicates that @status_icon can have a
+ * tooltip, in this case the status icon will be queried using
+ * #GtkStatusIcon::query-tooltip to determine whether it will provide a
+ * tooltip or not.
+ *
+ * Note that setting this property to %TRUE for the first time will change
+ * the event masks of the windows of this status icon to include leave-notify
+ * and motion-notify events. This will not be undone when the property is set
+ * to %FALSE again.
+ *
+ * Whether this property is respected is platform dependent.
+ * For plain text tooltips, use #GtkStatusIcon:tooltip-text in preference.
+ *
+ * Since: 2.16
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_HAS_TOOLTIP,
+ g_param_spec_boolean ("has-tooltip",
+ P_("Has tooltip"),
+ P_("Whether this tray icon has a tooltip"),
+ FALSE,
+ GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
+
+ /**
+ * GtkStatusIcon:tooltip-text:
+ *
+ * Sets the text of tooltip to be the given string.
+ *
+ * Also see gtk_tooltip_set_text().
+ *
+ * This is a convenience property which will take care of getting the
+ * tooltip shown if the given string is not %NULL.
+ * #GtkStatusIcon:has-tooltip will automatically be set to %TRUE and
+ * the default handler for the #GtkStatusIcon::query-tooltip signal
+ * will take care of displaying the tooltip.
+ *
+ * Note that some platforms have limitations on the length of tooltips
+ * that they allow on status icons, e.g. Windows only shows the first
+ * 64 characters.
+ *
+ * Since: 2.16
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_TOOLTIP_TEXT,
+ g_param_spec_string ("tooltip-text",
+ P_("Tooltip Text"),
+ P_("The contents of the tooltip for this widget"),
+ NULL,
+ GTK_PARAM_READWRITE));
+ /**
+ * GtkStatusIcon:tooltip-markup:
+ *
+ * Sets the text of tooltip to be the given string, which is marked up
+ * with the [Pango text markup language][PangoMarkupFormat].
+ * Also see gtk_tooltip_set_markup().
+ *
+ * This is a convenience property which will take care of getting the
+ * tooltip shown if the given string is not %NULL.
+ * #GtkStatusIcon:has-tooltip will automatically be set to %TRUE and
+ * the default handler for the #GtkStatusIcon::query-tooltip signal
+ * will take care of displaying the tooltip.
+ *
+ * On some platforms, embedded markup will be ignored.
+ *
+ * Since: 2.16
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_TOOLTIP_MARKUP,
+ g_param_spec_string ("tooltip-markup",
+ P_("Tooltip markup"),
+ P_("The contents of the tooltip for this tray icon"),
+ NULL,
+ GTK_PARAM_READWRITE));
+
+
+ /**
+ * GtkStatusIcon:title:
+ *
+ * The title of this tray icon. This should be a short, human-readable,
+ * localized string describing the tray icon. It may be used by tools
+ * like screen readers to render the tray icon.
+ *
+ * Since: 2.18
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_TITLE,
+ g_param_spec_string ("title",
+ P_("Title"),
+ P_("The title of this tray icon"),
+ NULL,
+ GTK_PARAM_READWRITE));
+
+ /**
+ * GtkStatusIcon::activate:
+ * @status_icon: the object which received the signal
+ *
+ * Gets emitted when the user activates the status icon.
+ * If and how status icons can activated is platform-dependent.
+ *
+ * Unlike most G_SIGNAL_ACTION signals, this signal is meant to
+ * be used by applications and should be wrapped by language bindings.
+ *
+ * Since: 2.10
+ */
+ status_icon_signals [ACTIVATE_SIGNAL] =
+ g_signal_new (I_("activate"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GtkStatusIconClass, activate),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ /**
+ * GtkStatusIcon::popup-menu:
+ * @status_icon: the object which received the signal
+ * @button: the button that was pressed, or 0 if the
+ * signal is not emitted in response to a button press event
+ * @activate_time: the timestamp of the event that
+ * triggered the signal emission
+ *
+ * Gets emitted when the user brings up the context menu
+ * of the status icon. Whether status icons can have context
+ * menus and how these are activated is platform-dependent.
+ *
+ * The @button and @activate_time parameters should be
+ * passed as the last to arguments to gtk_menu_popup().
+ *
+ * Unlike most G_SIGNAL_ACTION signals, this signal is meant to
+ * be used by applications and should be wrapped by language bindings.
+ *
+ * Since: 2.10
+ */
+ status_icon_signals [POPUP_MENU_SIGNAL] =
+ g_signal_new (I_("popup-menu"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GtkStatusIconClass, popup_menu),
+ NULL,
+ NULL,
+ _gtk_marshal_VOID__UINT_UINT,
+ G_TYPE_NONE,
+ 2,
+ G_TYPE_UINT,
+ G_TYPE_UINT);
+
+ /**
+ * GtkStatusIcon::size-changed:
+ * @status_icon: the object which received the signal
+ * @size: the new size
+ *
+ * Gets emitted when the size available for the image
+ * changes, e.g. because the notification area got resized.
+ *
+ * Returns: %TRUE if the icon was updated for the new
+ * size. Otherwise, GTK+ will scale the icon as necessary.
+ *
+ * Since: 2.10
+ */
+ status_icon_signals [SIZE_CHANGED_SIGNAL] =
+ g_signal_new (I_("size-changed"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkStatusIconClass, size_changed),
+ g_signal_accumulator_true_handled,
+ NULL,
+ _gtk_marshal_BOOLEAN__INT,
+ G_TYPE_BOOLEAN,
+ 1,
+ G_TYPE_INT);
+
+ /**
+ * GtkStatusIcon::button-press-event:
+ * @status_icon: the object which received the signal
+ * @event: (type Gdk.EventButton): the #GdkEventButton which triggered
+ * this signal
+ *
+ * The ::button-press-event signal will be emitted when a button
+ * (typically from a mouse) is pressed.
+ *
+ * Whether this event is emitted is platform-dependent. Use the ::activate
+ * and ::popup-menu signals in preference.
+ *
+ * Returns: %TRUE to stop other handlers from being invoked
+ * for the event. %FALSE to propagate the event further.
+ *
+ * Since: 2.14
+ */
+ status_icon_signals [BUTTON_PRESS_EVENT_SIGNAL] =
+ g_signal_new (I_("button_press_event"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkStatusIconClass, button_press_event),
+ g_signal_accumulator_true_handled, NULL,
+ _gtk_marshal_BOOLEAN__BOXED,
+ G_TYPE_BOOLEAN, 1,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+ /**
+ * GtkStatusIcon::button-release-event:
+ * @status_icon: the object which received the signal
+ * @event: (type Gdk.EventButton): the #GdkEventButton which triggered
+ * this signal
+ *
+ * The ::button-release-event signal will be emitted when a button
+ * (typically from a mouse) is released.
+ *
+ * Whether this event is emitted is platform-dependent. Use the ::activate
+ * and ::popup-menu signals in preference.
+ *
+ * Returns: %TRUE to stop other handlers from being invoked
+ * for the event. %FALSE to propagate the event further.
+ *
+ * Since: 2.14
+ */
+ status_icon_signals [BUTTON_RELEASE_EVENT_SIGNAL] =
+ g_signal_new (I_("button_release_event"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkStatusIconClass, button_release_event),
+ g_signal_accumulator_true_handled, NULL,
+ _gtk_marshal_BOOLEAN__BOXED,
+ G_TYPE_BOOLEAN, 1,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+ /**
+ * GtkStatusIcon::scroll-event:
+ * @status_icon: the object which received the signal.
+ * @event: (type Gdk.EventScroll): the #GdkEventScroll which triggered
+ * this signal
+ *
+ * The ::scroll-event signal is emitted when a button in the 4 to 7
+ * range is pressed. Wheel mice are usually configured to generate
+ * button press events for buttons 4 and 5 when the wheel is turned.
+ *
+ * Whether this event is emitted is platform-dependent.
+ *
+ * Returns: %TRUE to stop other handlers from being invoked for the event.
+ * %FALSE to propagate the event further.
+ *
+ * Since: 2.16
+ */
+ status_icon_signals[SCROLL_EVENT_SIGNAL] =
+ g_signal_new (I_("scroll_event"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkStatusIconClass, scroll_event),
+ g_signal_accumulator_true_handled, NULL,
+ _gtk_marshal_BOOLEAN__BOXED,
+ G_TYPE_BOOLEAN, 1,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+ /**
+ * GtkStatusIcon::query-tooltip:
+ * @status_icon: the object which received the signal
+ * @x: the x coordinate of the cursor position where the request has been
+ * emitted, relative to @status_icon
+ * @y: the y coordinate of the cursor position where the request has been
+ * emitted, relative to @status_icon
+ * @keyboard_mode: %TRUE if the tooltip was trigged using the keyboard
+ * @tooltip: a #GtkTooltip
+ *
+ * Emitted when the hover timeout has expired with the
+ * cursor hovering above @status_icon; or emitted when @status_icon got
+ * focus in keyboard mode.
+ *
+ * Using the given coordinates, the signal handler should determine
+ * whether a tooltip should be shown for @status_icon. If this is
+ * the case %TRUE should be returned, %FALSE otherwise. Note that if
+ * @keyboard_mode is %TRUE, the values of @x and @y are undefined and
+ * should not be used.
+ *
+ * The signal handler is free to manipulate @tooltip with the therefore
+ * destined function calls.
+ *
+ * Whether this signal is emitted is platform-dependent.
+ * For plain text tooltips, use #GtkStatusIcon:tooltip-text in preference.
+ *
+ * Returns: %TRUE if @tooltip should be shown right now, %FALSE otherwise.
+ *
+ * Since: 2.16
+ */
+ status_icon_signals [QUERY_TOOLTIP_SIGNAL] =
+ g_signal_new (I_("query_tooltip"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkStatusIconClass, query_tooltip),
+ g_signal_accumulator_true_handled, NULL,
+ _gtk_marshal_BOOLEAN__INT_INT_BOOLEAN_OBJECT,
+ G_TYPE_BOOLEAN, 4,
+ G_TYPE_INT,
+ G_TYPE_INT,
+ G_TYPE_BOOLEAN,
+ GTK_TYPE_TOOLTIP);
+}
+
+#ifdef GDK_WINDOWING_WIN32
+
+static void
+build_button_event (GtkStatusIconPrivate *priv,
+ GdkEventButton *e,
+ guint button)
+{
+ POINT pos;
+ GdkRectangle monitor0;
+
+ /* We know that gdk/win32 puts the primary monitor at index 0 */
+ gdk_screen_get_monitor_geometry (gdk_screen_get_default (), 0, &monitor0);
+ e->window = g_object_ref (gdk_get_default_root_window ());
+ e->send_event = TRUE;
+ e->time = GetTickCount ();
+ GetCursorPos (&pos);
+ priv->last_click_x = e->x = pos.x + monitor0.x;
+ priv->last_click_y = e->y = pos.y + monitor0.y;
+ e->axes = NULL;
+ e->state = 0;
+ e->button = button;
+ //FIXME: e->device = gdk_display_get_default ()->core_pointer;
+ e->x_root = e->x;
+ e->y_root = e->y;
+}
+
+typedef struct
+{
+ GtkStatusIcon *status_icon;
+ GdkEventButton *event;
+} ButtonCallbackData;
+
+static gboolean
+button_callback (gpointer data)
+{
+ ButtonCallbackData *bc = (ButtonCallbackData *) data;
+
+ if (bc->event->type == GDK_BUTTON_PRESS)
+ gtk_status_icon_button_press (bc->status_icon, bc->event);
+ else
+ gtk_status_icon_button_release (bc->status_icon, bc->event);
+
+ gdk_event_free ((GdkEvent *) bc->event);
+ g_free (data);
+
+ return G_SOURCE_REMOVE;
+}
+
+static UINT taskbar_created_msg = 0;
+static GSList *status_icons = NULL;
+
+static LRESULT CALLBACK
+wndproc (HWND hwnd,
+ UINT message,
+ WPARAM wparam,
+ LPARAM lparam)
+{
+ if (message == taskbar_created_msg)
+ {
+ GSList *rover;
+
+ for (rover = status_icons; rover != NULL; rover = rover->next)
+ {
+ GtkStatusIcon *status_icon = GTK_STATUS_ICON (rover->data);
+ GtkStatusIconPrivate *priv = status_icon->priv;
+
+ priv->nid.hWnd = hwnd;
+ priv->nid.uID = GPOINTER_TO_UINT (status_icon);
+ priv->nid.uCallbackMessage = WM_GTK_TRAY_NOTIFICATION;
+ priv->nid.uFlags = NIF_MESSAGE;
+
+ if (!Shell_NotifyIconW (NIM_ADD, &priv->nid))
+ {
+ g_warning (G_STRLOC ": Shell_NotifyIcon(NIM_ADD) failed");
+ priv->nid.hWnd = NULL;
+ continue;
+ }
+
+ gtk_status_icon_update_image (status_icon);
+ }
+ return 0;
+ }
+
+ if (message == WM_GTK_TRAY_NOTIFICATION)
+ {
+ ButtonCallbackData *bc;
+ guint button;
+
+ switch (lparam)
+ {
+ case WM_LBUTTONDOWN:
+ button = 1;
+ goto buttondown0;
+
+ case WM_MBUTTONDOWN:
+ button = 2;
+ goto buttondown0;
+
+ case WM_RBUTTONDOWN:
+ button = 3;
+ goto buttondown0;
+
+ case WM_XBUTTONDOWN:
+ if (HIWORD (wparam) == XBUTTON1)
+ button = 4;
+ else
+ button = 5;
+
+ buttondown0:
+ bc = g_new (ButtonCallbackData, 1);
+ bc->event = (GdkEventButton *) gdk_event_new (GDK_BUTTON_PRESS);
+ bc->status_icon = GTK_STATUS_ICON (wparam);
+ build_button_event (bc->status_icon->priv, bc->event, button);
+ g_idle_add (button_callback, bc);
+ break;
+
+ case WM_LBUTTONUP:
+ button = 1;
+ goto buttonup0;
+
+ case WM_MBUTTONUP:
+ button = 2;
+ goto buttonup0;
+
+ case WM_RBUTTONUP:
+ button = 3;
+ goto buttonup0;
+
+ case WM_XBUTTONUP:
+ if (HIWORD (wparam) == XBUTTON1)
+ button = 4;
+ else
+ button = 5;
+
+ buttonup0:
+ bc = g_new (ButtonCallbackData, 1);
+ bc->event = (GdkEventButton *) gdk_event_new (GDK_BUTTON_RELEASE);
+ bc->status_icon = GTK_STATUS_ICON (wparam);
+ build_button_event (bc->status_icon->priv, bc->event, button);
+ g_idle_add (button_callback, bc);
+ break;
+
+ default :
+ break;
+ }
+ return 0;
+ }
+ else
+ {
+ return DefWindowProc (hwnd, message, wparam, lparam);
+ }
+}
+
+static HWND
+create_tray_observer (void)
+{
+ WNDCLASS wclass;
+ static HWND hwnd = NULL;
+ ATOM klass;
+ HINSTANCE hmodule = GetModuleHandle (NULL);
+
+ if (hwnd)
+ return hwnd;
+
+ taskbar_created_msg = RegisterWindowMessage("TaskbarCreated");
+
+ memset (&wclass, 0, sizeof(WNDCLASS));
+ wclass.lpszClassName = "gtkstatusicon-observer";
+ wclass.lpfnWndProc = wndproc;
+ wclass.hInstance = hmodule;
+
+ klass = RegisterClass (&wclass);
+ if (!klass)
+ return NULL;
+
+ hwnd = CreateWindow (MAKEINTRESOURCE (klass),
+ NULL, WS_POPUP,
+ 0, 0, 1, 1, NULL, NULL,
+ hmodule, NULL);
+ if (!hwnd)
+ {
+ UnregisterClass (MAKEINTRESOURCE(klass), hmodule);
+ return NULL;
+ }
+
+ return hwnd;
+}
+
+#endif
+
+static void
+gtk_status_icon_init (GtkStatusIcon *status_icon)
+{
+ GtkStatusIconPrivate *priv;
+
+ priv = gtk_status_icon_get_instance_private (status_icon);
+ status_icon->priv = priv;
+
+ priv->icon_helper = _gtk_icon_helper_new ();
+ _gtk_icon_helper_set_force_scale_pixbuf (priv->icon_helper, TRUE);
+ priv->visible = TRUE;
+
+#ifdef GDK_WINDOWING_X11
+ if (GDK_IS_X11_DISPLAY (gdk_display_get_default ()))
+ {
+ priv->size = 0;
+ priv->tray_icon = GTK_WIDGET (_gtk_tray_icon_new (NULL));
+
+ gtk_widget_add_events (GTK_WIDGET (priv->tray_icon),
+ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
+ GDK_SCROLL_MASK);
+
+ g_signal_connect_swapped (priv->tray_icon, "key-press-event",
+ G_CALLBACK (gtk_status_icon_key_press), status_icon);
+ g_signal_connect_swapped (priv->tray_icon, "popup-menu",
+ G_CALLBACK (gtk_status_icon_popup_menu), status_icon);
+ g_signal_connect_swapped (priv->tray_icon, "notify::embedded",
+ G_CALLBACK (gtk_status_icon_embedded_changed), status_icon);
+ g_signal_connect_swapped (priv->tray_icon, "notify::orientation",
+ G_CALLBACK (gtk_status_icon_orientation_changed), status_icon);
+ g_signal_connect_swapped (priv->tray_icon, "notify::padding",
+ G_CALLBACK (gtk_status_icon_padding_changed), status_icon);
+ g_signal_connect_swapped (priv->tray_icon, "notify::icon-size",
+ G_CALLBACK (gtk_status_icon_icon_size_changed), status_icon);
+ g_signal_connect_swapped (priv->tray_icon, "notify::fg-color",
+ G_CALLBACK (gtk_status_icon_fg_changed), status_icon);
+ g_signal_connect (priv->tray_icon, "notify::error-color",
+ G_CALLBACK (gtk_status_icon_color_changed), status_icon);
+ g_signal_connect (priv->tray_icon, "notify::warning-color",
+ G_CALLBACK (gtk_status_icon_color_changed), status_icon);
+ g_signal_connect (priv->tray_icon, "notify::success-color",
+ G_CALLBACK (gtk_status_icon_color_changed), status_icon);
+ g_signal_connect_swapped (priv->tray_icon, "button-press-event",
+ G_CALLBACK (gtk_status_icon_button_press), status_icon);
+ g_signal_connect_swapped (priv->tray_icon, "button-release-event",
+ G_CALLBACK (gtk_status_icon_button_release), status_icon);
+ g_signal_connect_swapped (priv->tray_icon, "scroll-event",
+ G_CALLBACK (gtk_status_icon_scroll), status_icon);
+ g_signal_connect_swapped (priv->tray_icon, "query-tooltip",
+ G_CALLBACK (gtk_status_icon_query_tooltip), status_icon);
+ g_signal_connect_swapped (priv->tray_icon, "screen-changed",
+ G_CALLBACK (gtk_status_icon_screen_changed), status_icon);
+ priv->image = gtk_image_new ();
+ gtk_widget_set_can_focus (priv->image, TRUE);
+ gtk_container_add (GTK_CONTAINER (priv->tray_icon), priv->image);
+ gtk_widget_show (priv->image);
+
+ /* Force-initialize the symbolic colors */
+ g_object_notify (G_OBJECT (priv->tray_icon), "fg-color");
+ g_object_notify (G_OBJECT (priv->tray_icon), "error-color");
+ g_object_notify (G_OBJECT (priv->tray_icon), "warning-color");
+ g_object_notify (G_OBJECT (priv->tray_icon), "success-color");
+
+ g_signal_connect_swapped (priv->image, "size-allocate",
+ G_CALLBACK (gtk_status_icon_size_allocate), status_icon);
+ }
+#else /* !GDK_WINDOWING_X11 */
+ priv->dummy_widget = gtk_label_new ("");
+#endif
+
+#ifdef GDK_WINDOWING_WIN32
+
+ /* Get position and orientation of Windows taskbar. */
+ {
+ APPBARDATA abd;
+
+ abd.cbSize = sizeof (abd);
+ SHAppBarMessage (ABM_GETTASKBARPOS, &abd);
+ if (abd.rc.bottom - abd.rc.top > abd.rc.right - abd.rc.left)
+ priv->orientation = GTK_ORIENTATION_VERTICAL;
+ else
+ priv->orientation = GTK_ORIENTATION_HORIZONTAL;
+
+ priv->taskbar_top = abd.rc.top;
+ }
+
+ priv->last_click_x = priv->last_click_y = 0;
+
+ /* Are the system tray icons always 16 pixels square? */
+ priv->size = 16;
+
+ memset (&priv->nid, 0, sizeof (priv->nid));
+
+ priv->nid.hWnd = create_tray_observer ();
+ priv->nid.uID = GPOINTER_TO_UINT (status_icon);
+ priv->nid.uCallbackMessage = WM_GTK_TRAY_NOTIFICATION;
+ priv->nid.uFlags = NIF_MESSAGE;
+
+ /* To help win7 identify the icon create it with an application "unique" tip */
+ if (g_get_prgname ())
+ {
+ WCHAR *wcs = g_utf8_to_utf16 (g_get_prgname (), -1, NULL, NULL, NULL);
+
+ priv->nid.uFlags |= NIF_TIP;
+ wcsncpy (priv->nid.szTip, wcs, G_N_ELEMENTS (priv->nid.szTip) - 1);
+ priv->nid.szTip[G_N_ELEMENTS (priv->nid.szTip) - 1] = 0;
+ g_free (wcs);
+ }
+
+ if (!Shell_NotifyIconW (NIM_ADD, &priv->nid))
+ {
+ g_warning (G_STRLOC ": Shell_NotifyIcon(NIM_ADD) failed");
+ priv->nid.hWnd = NULL;
+ }
+
+ status_icons = g_slist_append (status_icons, status_icon);
+
+#endif
+
+#ifdef GDK_WINDOWING_QUARTZ
+ QUARTZ_POOL_ALLOC;
+
+ priv->status_item = [[GtkQuartzStatusIcon alloc] initWithStatusIcon:status_icon];
+ priv->size = [priv->status_item getHeight];
+
+ QUARTZ_POOL_RELEASE;
+
+#endif
+}
+
+static void
+gtk_status_icon_constructed (GObject *object)
+{
+ G_OBJECT_CLASS (gtk_status_icon_parent_class)->constructed (object);
+
+#ifdef GDK_WINDOWING_X11
+ {
+ GtkStatusIcon *status_icon = GTK_STATUS_ICON (object);
+ GtkStatusIconPrivate *priv = status_icon->priv;
+
+ if (priv->visible && priv->tray_icon)
+ gtk_widget_show (priv->tray_icon);
+ }
+#endif
+}
+
+static void
+gtk_status_icon_finalize (GObject *object)
+{
+ GtkStatusIcon *status_icon = GTK_STATUS_ICON (object);
+ GtkStatusIconPrivate *priv = status_icon->priv;
+
+ gtk_status_icon_reset_image_data (status_icon);
+ g_clear_object (&priv->icon_helper);
+
+#ifdef GDK_WINDOWING_X11
+ if (priv->tray_icon)
+ {
+ g_signal_handlers_disconnect_by_func (priv->tray_icon,
+ gtk_status_icon_key_press, status_icon);
+ g_signal_handlers_disconnect_by_func (priv->tray_icon,
+ gtk_status_icon_popup_menu, status_icon);
+ g_signal_handlers_disconnect_by_func (priv->tray_icon,
+ gtk_status_icon_embedded_changed, status_icon);
+ g_signal_handlers_disconnect_by_func (priv->tray_icon,
+ gtk_status_icon_orientation_changed, status_icon);
+ g_signal_handlers_disconnect_by_func (priv->tray_icon,
+ gtk_status_icon_padding_changed, status_icon);
+ g_signal_handlers_disconnect_by_func (priv->tray_icon,
+ gtk_status_icon_icon_size_changed, status_icon);
+ g_signal_handlers_disconnect_by_func (priv->tray_icon,
+ gtk_status_icon_fg_changed, status_icon);
+ g_signal_handlers_disconnect_by_func (priv->tray_icon,
+ gtk_status_icon_color_changed, status_icon);
+ g_signal_handlers_disconnect_by_func (priv->tray_icon,
+ gtk_status_icon_button_press, status_icon);
+ g_signal_handlers_disconnect_by_func (priv->tray_icon,
+ gtk_status_icon_button_release, status_icon);
+ g_signal_handlers_disconnect_by_func (priv->tray_icon,
+ gtk_status_icon_scroll, status_icon);
+ g_signal_handlers_disconnect_by_func (priv->tray_icon,
+ gtk_status_icon_query_tooltip, status_icon);
+ g_signal_handlers_disconnect_by_func (priv->tray_icon,
+ gtk_status_icon_screen_changed, status_icon);
+ gtk_widget_destroy (priv->image);
+ gtk_widget_destroy (priv->tray_icon);
+ }
+#else /* !GDK_WINDOWING_X11 */
+ gtk_widget_destroy (priv->dummy_widget);
+#endif
+
+#ifdef GDK_WINDOWING_WIN32
+ if (priv->nid.hWnd != NULL && priv->visible)
+ Shell_NotifyIconW (NIM_DELETE, &priv->nid);
+ if (priv->nid.hIcon)
+ DestroyIcon (priv->nid.hIcon);
+ g_free (priv->tooltip_text);
+
+ status_icons = g_slist_remove (status_icons, status_icon);
+#endif
+
+#ifdef GDK_WINDOWING_QUARTZ
+ QUARTZ_POOL_ALLOC;
+ [priv->status_item release];
+ QUARTZ_POOL_RELEASE;
+ g_free (priv->tooltip_text);
+#endif
+
+ G_OBJECT_CLASS (gtk_status_icon_parent_class)->finalize (object);
+}
+
+static void
+gtk_status_icon_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GtkStatusIcon *status_icon = GTK_STATUS_ICON (object);
+
+ switch (prop_id)
+ {
+ case PROP_PIXBUF:
+ gtk_status_icon_set_from_pixbuf (status_icon, g_value_get_object (value));
+ break;
+ case PROP_FILE:
+ gtk_status_icon_set_from_file (status_icon, g_value_get_string (value));
+ break;
+ case PROP_STOCK:
+ gtk_status_icon_set_from_stock (status_icon, g_value_get_string (value));
+ break;
+ case PROP_ICON_NAME:
+ gtk_status_icon_set_from_icon_name (status_icon, g_value_get_string (value));
+ break;
+ case PROP_GICON:
+ gtk_status_icon_set_from_gicon (status_icon, g_value_get_object (value));
+ break;
+ case PROP_SCREEN:
+ gtk_status_icon_set_screen (status_icon, g_value_get_object (value));
+ break;
+ case PROP_VISIBLE:
+ gtk_status_icon_set_visible (status_icon, g_value_get_boolean (value));
+ break;
+ case PROP_HAS_TOOLTIP:
+ gtk_status_icon_set_has_tooltip (status_icon, g_value_get_boolean (value));
+ break;
+ case PROP_TOOLTIP_TEXT:
+ gtk_status_icon_set_tooltip_text (status_icon, g_value_get_string (value));
+ break;
+ case PROP_TOOLTIP_MARKUP:
+ gtk_status_icon_set_tooltip_markup (status_icon, g_value_get_string (value));
+ break;
+ case PROP_TITLE:
+ gtk_status_icon_set_title (status_icon, g_value_get_string (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gtk_status_icon_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkStatusIcon *status_icon = GTK_STATUS_ICON (object);
+
+ switch (prop_id)
+ {
+ case PROP_PIXBUF:
+ g_value_set_object (value, gtk_status_icon_get_pixbuf (status_icon));
+ break;
+ case PROP_STOCK:
+ g_value_set_string (value, gtk_status_icon_get_stock (status_icon));
+ break;
+ case PROP_ICON_NAME:
+ g_value_set_string (value, gtk_status_icon_get_icon_name (status_icon));
+ break;
+ case PROP_GICON:
+ g_value_set_object (value, gtk_status_icon_get_gicon (status_icon));
+ break;
+ case PROP_STORAGE_TYPE:
+ g_value_set_enum (value, gtk_status_icon_get_storage_type (status_icon));
+ break;
+ case PROP_SIZE:
+ g_value_set_int (value, gtk_status_icon_get_size (status_icon));
+ break;
+ case PROP_SCREEN:
+ g_value_set_object (value, gtk_status_icon_get_screen (status_icon));
+ break;
+ case PROP_VISIBLE:
+ g_value_set_boolean (value, gtk_status_icon_get_visible (status_icon));
+ break;
+ case PROP_EMBEDDED:
+ g_value_set_boolean (value, gtk_status_icon_is_embedded (status_icon));
+ break;
+ case PROP_ORIENTATION:
+#ifdef GDK_WINDOWING_X11
+ if (status_icon->priv->tray_icon)
+ g_value_set_enum (value, _gtk_tray_icon_get_orientation (GTK_TRAY_ICON (status_icon->priv->tray_icon)));
+ else
+ g_value_set_enum (value, GTK_ORIENTATION_HORIZONTAL);
+#endif
+#ifdef GDK_WINDOWING_WIN32
+ g_value_set_enum (value, status_icon->priv->orientation);
+#endif
+ break;
+ case PROP_HAS_TOOLTIP:
+ g_value_set_boolean (value, gtk_status_icon_get_has_tooltip (status_icon));
+ break;
+ case PROP_TOOLTIP_TEXT:
+ g_value_set_string (value, gtk_status_icon_get_tooltip_text (status_icon));
+ break;
+ case PROP_TOOLTIP_MARKUP:
+ g_value_set_string (value, gtk_status_icon_get_tooltip_markup (status_icon));
+ break;
+ case PROP_TITLE:
+ g_value_set_string (value, gtk_status_icon_get_title (status_icon));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * gtk_status_icon_new:
+ *
+ * Creates an empty status icon object.
+ *
+ * Returns: a new #GtkStatusIcon
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+GtkStatusIcon *
+gtk_status_icon_new (void)
+{
+ return g_object_new (GTK_TYPE_STATUS_ICON, NULL);
+}
+
+/**
+ * gtk_status_icon_new_from_pixbuf:
+ * @pixbuf: a #GdkPixbuf
+ *
+ * Creates a status icon displaying @pixbuf.
+ *
+ * The image will be scaled down to fit in the available
+ * space in the notification area, if necessary.
+ *
+ * Returns: a new #GtkStatusIcon
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+GtkStatusIcon *
+gtk_status_icon_new_from_pixbuf (GdkPixbuf *pixbuf)
+{
+ return g_object_new (GTK_TYPE_STATUS_ICON,
+ "pixbuf", pixbuf,
+ NULL);
+}
+
+/**
+ * gtk_status_icon_new_from_file:
+ * @filename: (type filename): a filename
+ *
+ * Creates a status icon displaying the file @filename.
+ *
+ * The image will be scaled down to fit in the available
+ * space in the notification area, if necessary.
+ *
+ * Returns: a new #GtkStatusIcon
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+GtkStatusIcon *
+gtk_status_icon_new_from_file (const gchar *filename)
+{
+ return g_object_new (GTK_TYPE_STATUS_ICON,
+ "file", filename,
+ NULL);
+}
+
+/**
+ * gtk_status_icon_new_from_stock:
+ * @stock_id: a stock icon id
+ *
+ * Creates a status icon displaying a stock icon. Sample stock icon
+ * names are #GTK_STOCK_OPEN, #GTK_STOCK_QUIT. You can register your
+ * own stock icon names, see gtk_icon_factory_add_default() and
+ * gtk_icon_factory_add().
+ *
+ * Returns: a new #GtkStatusIcon
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.10: Use gtk_status_icon_new_from_icon_name() instead.
+ **/
+GtkStatusIcon *
+gtk_status_icon_new_from_stock (const gchar *stock_id)
+{
+ return g_object_new (GTK_TYPE_STATUS_ICON,
+ "stock", stock_id,
+ NULL);
+}
+
+/**
+ * gtk_status_icon_new_from_icon_name:
+ * @icon_name: an icon name
+ *
+ * Creates a status icon displaying an icon from the current icon theme.
+ * If the current icon theme is changed, the icon will be updated
+ * appropriately.
+ *
+ * Returns: a new #GtkStatusIcon
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+GtkStatusIcon *
+gtk_status_icon_new_from_icon_name (const gchar *icon_name)
+{
+ return g_object_new (GTK_TYPE_STATUS_ICON,
+ "icon-name", icon_name,
+ NULL);
+}
+
+/**
+ * gtk_status_icon_new_from_gicon:
+ * @icon: a #GIcon
+ *
+ * Creates a status icon displaying a #GIcon. If the icon is a
+ * themed icon, it will be updated when the theme changes.
+ *
+ * Returns: a new #GtkStatusIcon
+ *
+ * Since: 2.14
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+GtkStatusIcon *
+gtk_status_icon_new_from_gicon (GIcon *icon)
+{
+ return g_object_new (GTK_TYPE_STATUS_ICON,
+ "gicon", icon,
+ NULL);
+}
+
+static void
+emit_activate_signal (GtkStatusIcon *status_icon)
+{
+ g_signal_emit (status_icon,
+ status_icon_signals [ACTIVATE_SIGNAL], 0);
+}
+
+static void
+emit_popup_menu_signal (GtkStatusIcon *status_icon,
+ guint button,
+ guint32 activate_time)
+{
+ g_signal_emit (status_icon,
+ status_icon_signals [POPUP_MENU_SIGNAL], 0,
+ button,
+ activate_time);
+}
+
+#ifdef GDK_WINDOWING_X11
+
+static gboolean
+emit_size_changed_signal (GtkStatusIcon *status_icon,
+ gint size)
+{
+ gboolean handled = FALSE;
+
+ g_signal_emit (status_icon,
+ status_icon_signals [SIZE_CHANGED_SIGNAL], 0,
+ size,
+ &handled);
+
+ return handled;
+}
+
+#endif
+
+/* rounds the pixel size to the nearest size avaiable in the theme */
+static gint
+round_pixel_size (GtkWidget *widget,
+ gint pixel_size)
+{
+ GtkIconSize s;
+ gint w, h, d, dist, size;
+
+ dist = G_MAXINT;
+ size = 0;
+
+ for (s = GTK_ICON_SIZE_MENU; s <= GTK_ICON_SIZE_DIALOG; s++)
+ {
+ if (gtk_icon_size_lookup (s, &w, &h))
+ {
+ d = MAX (abs (pixel_size - w), abs (pixel_size - h));
+ if (d < dist)
+ {
+ dist = d;
+ size = MAX (w, h);
+ }
+ }
+ }
+
+ return size;
+}
+
+static void
+gtk_status_icon_update_image (GtkStatusIcon *status_icon)
+{
+ GtkStatusIconPrivate *priv = status_icon->priv;
+#ifdef GDK_WINDOWING_WIN32
+ HICON prev_hicon;
+#endif
+ GtkStyleContext *context;
+ GtkWidget *widget;
+ GdkPixbuf *pixbuf;
+ gint round_size;
+
+#ifdef GDK_WINDOWING_X11
+ widget = priv->image;
+#else
+ widget = priv->dummy_widget;
+#endif
+
+ if (widget == NULL)
+ return;
+
+ context = gtk_widget_get_style_context (widget);
+ round_size = round_pixel_size (widget, priv->size);
+
+ _gtk_icon_helper_set_pixel_size (priv->icon_helper, round_size);
+ pixbuf = _gtk_icon_helper_ensure_pixbuf (priv->icon_helper, context);
+
+ if (pixbuf != NULL)
+ {
+#ifdef GDK_WINDOWING_X11
+ gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), pixbuf);
+#endif
+#ifdef GDK_WINDOWING_WIN32
+ prev_hicon = priv->nid.hIcon;
+ priv->nid.hIcon = gdk_win32_pixbuf_to_hicon_libgtk_only (pixbuf);
+ priv->nid.uFlags |= NIF_ICON;
+ if (priv->nid.hWnd != NULL && priv->visible)
+ if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
+ g_warning (G_STRLOC ": Shell_NotifyIcon(NIM_MODIFY) failed");
+ if (prev_hicon)
+ DestroyIcon (prev_hicon);
+#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ QUARTZ_POOL_ALLOC;
+ [priv->status_item setImage:pixbuf];
+ QUARTZ_POOL_RELEASE;
+#endif
+ }
+ else
+ {
+#ifdef GDK_WINDOWING_X11
+ gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), NULL);
+#endif
+#ifdef GDK_WINDOWING_WIN32
+ priv->nid.uFlags &= ~NIF_ICON;
+ if (priv->nid.hWnd != NULL && priv->visible)
+ if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
+ g_warning (G_STRLOC ": Shell_NotifyIcon(NIM_MODIFY) failed");
+#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ [priv->status_item setImage:NULL];
+#endif
+ }
+
+ g_clear_object (&pixbuf);
+}
+
+#ifdef GDK_WINDOWING_X11
+
+static void
+gtk_status_icon_size_allocate (GtkStatusIcon *status_icon,
+ GtkAllocation *allocation)
+{
+ GtkStatusIconPrivate *priv = status_icon->priv;
+ GtkOrientation orientation;
+ gint size;
+
+ orientation = _gtk_tray_icon_get_orientation (GTK_TRAY_ICON (priv->tray_icon));
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ size = allocation->height;
+ else
+ size = allocation->width;
+
+ if (priv->size != size)
+ {
+ priv->size = size;
+
+ g_object_notify (G_OBJECT (status_icon), "size");
+
+ if (!emit_size_changed_signal (status_icon, size))
+ gtk_status_icon_update_image (status_icon);
+ }
+}
+
+static void
+gtk_status_icon_screen_changed (GtkStatusIcon *status_icon,
+ GdkScreen *old_screen)
+{
+ GtkStatusIconPrivate *priv = status_icon->priv;
+
+ if (gtk_widget_get_screen (priv->tray_icon) != old_screen)
+ {
+ g_object_notify (G_OBJECT (status_icon), "screen");
+ }
+}
+
+static void
+gtk_status_icon_padding_changed (GtkStatusIcon *status_icon)
+{
+ GtkStatusIconPrivate *priv = status_icon->priv;
+ GtkOrientation orientation;
+ gint padding;
+
+ orientation = _gtk_tray_icon_get_orientation (GTK_TRAY_ICON (priv->tray_icon));
+ padding = _gtk_tray_icon_get_padding (GTK_TRAY_ICON (priv->tray_icon));
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ {
+ gtk_widget_set_margin_start (priv->image, padding);
+ gtk_widget_set_margin_end (priv->image, padding);
+ }
+ else
+ {
+ gtk_widget_set_margin_bottom (priv->image, padding);
+ gtk_widget_set_margin_top (priv->image, padding);
+ }
+}
+
+static void
+gtk_status_icon_icon_size_changed (GtkStatusIcon *status_icon)
+{
+ GtkStatusIconPrivate *priv = status_icon->priv;
+ gint icon_size;
+
+ icon_size = _gtk_tray_icon_get_icon_size (GTK_TRAY_ICON (priv->tray_icon));
+
+ if (icon_size != 0)
+ gtk_image_set_pixel_size (GTK_IMAGE (priv->image), icon_size);
+ else
+ gtk_image_set_pixel_size (GTK_IMAGE (priv->image), -1);
+}
+
+static void
+gtk_status_icon_embedded_changed (GtkStatusIcon *status_icon)
+{
+ gtk_status_icon_padding_changed (status_icon);
+ gtk_status_icon_icon_size_changed (status_icon);
+ g_object_notify (G_OBJECT (status_icon), "embedded");
+}
+
+static void
+gtk_status_icon_orientation_changed (GtkStatusIcon *status_icon)
+{
+ gtk_status_icon_padding_changed (status_icon);
+ g_object_notify (G_OBJECT (status_icon), "orientation");
+}
+
+static void
+gtk_status_icon_fg_changed (GtkStatusIcon *status_icon)
+{
+ GtkStatusIconPrivate *priv = status_icon->priv;
+ GdkRGBA *rgba;
+
+ g_object_get (priv->tray_icon, "fg-color", &rgba, NULL);
+
+ gtk_widget_override_color (priv->image, GTK_STATE_FLAG_NORMAL, rgba);
+
+ gdk_rgba_free (rgba);
+}
+
+static void
+gtk_status_icon_color_changed (GtkTrayIcon *tray,
+ GParamSpec *pspec,
+ GtkStatusIcon *status_icon)
+{
+ GtkStatusIconPrivate *priv = status_icon->priv;
+ const gchar *name;
+
+ switch (pspec->name[0])
+ {
+ case 'e':
+ name = "error";
+ break;
+ case 'w':
+ name = "warning";
+ break;
+ case 's':
+ name = "success";
+ break;
+ default:
+ name = NULL;
+ break;
+ }
+
+ if (name)
+ {
+ GdkRGBA rgba;
+
+ g_object_get (priv->tray_icon, pspec->name, &rgba, NULL);
+
+ rgba.alpha = 1;
+
+ gtk_widget_override_symbolic_color (priv->image, name, &rgba);
+ }
+}
+
+static gboolean
+gtk_status_icon_key_press (GtkStatusIcon *status_icon,
+ GdkEventKey *event)
+{
+ guint state, keyval;
+
+ state = event->state & gtk_accelerator_get_default_mod_mask ();
+ keyval = event->keyval;
+ if (state == 0 &&
+ (keyval == GDK_KEY_Return ||
+ keyval == GDK_KEY_KP_Enter ||
+ keyval == GDK_KEY_ISO_Enter ||
+ keyval == GDK_KEY_space ||
+ keyval == GDK_KEY_KP_Space))
+ {
+ emit_activate_signal (status_icon);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+gtk_status_icon_popup_menu (GtkStatusIcon *status_icon)
+{
+ emit_popup_menu_signal (status_icon, 0, gtk_get_current_event_time ());
+}
+
+#endif /* GDK_WINDOWING_X11 */
+
+static gboolean
+gtk_status_icon_button_press (GtkStatusIcon *status_icon,
+ GdkEventButton *event)
+{
+ gboolean handled = FALSE;
+
+ g_signal_emit (status_icon,
+ status_icon_signals [BUTTON_PRESS_EVENT_SIGNAL], 0,
+ event, &handled);
+ if (handled)
+ return TRUE;
+
+ if (gdk_event_triggers_context_menu ((GdkEvent *) event))
+ {
+ emit_popup_menu_signal (status_icon, event->button, event->time);
+ return TRUE;
+ }
+ else if (event->button == GDK_BUTTON_PRIMARY && event->type == GDK_BUTTON_PRESS)
+ {
+ emit_activate_signal (status_icon);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+gtk_status_icon_button_release (GtkStatusIcon *status_icon,
+ GdkEventButton *event)
+{
+ gboolean handled = FALSE;
+ g_signal_emit (status_icon,
+ status_icon_signals [BUTTON_RELEASE_EVENT_SIGNAL], 0,
+ event, &handled);
+ return handled;
+}
+
+#ifdef GDK_WINDOWING_X11
+
+static gboolean
+gtk_status_icon_scroll (GtkStatusIcon *status_icon,
+ GdkEventScroll *event)
+{
+ gboolean handled = FALSE;
+ g_signal_emit (status_icon,
+ status_icon_signals [SCROLL_EVENT_SIGNAL], 0,
+ event, &handled);
+ return handled;
+}
+
+static gboolean
+gtk_status_icon_query_tooltip (GtkStatusIcon *status_icon,
+ gint x,
+ gint y,
+ gboolean keyboard_tip,
+ GtkTooltip *tooltip)
+{
+ gboolean handled = FALSE;
+ g_signal_emit (status_icon,
+ status_icon_signals [QUERY_TOOLTIP_SIGNAL], 0,
+ x, y, keyboard_tip, tooltip, &handled);
+ return handled;
+}
+
+#endif /* GDK_WINDOWING_X11 */
+
+static void
+gtk_status_icon_reset_image_data (GtkStatusIcon *status_icon)
+{
+ GtkStatusIconPrivate *priv = status_icon->priv;
+ GtkImageType storage_type = _gtk_icon_helper_get_storage_type (priv->icon_helper);
+
+ switch (storage_type)
+ {
+ case GTK_IMAGE_PIXBUF:
+ g_object_notify (G_OBJECT (status_icon), "pixbuf");
+ break;
+ case GTK_IMAGE_STOCK:
+ g_object_notify (G_OBJECT (status_icon), "stock");
+ break;
+ case GTK_IMAGE_ICON_NAME:
+ g_object_notify (G_OBJECT (status_icon), "icon-name");
+ break;
+ case GTK_IMAGE_GICON:
+ g_object_notify (G_OBJECT (status_icon), "gicon");
+ break;
+ case GTK_IMAGE_EMPTY:
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ _gtk_icon_helper_clear (priv->icon_helper);
+ g_object_notify (G_OBJECT (status_icon), "storage-type");
+}
+
+static void
+gtk_status_icon_set_image (GtkStatusIcon *status_icon,
+ GtkImageType storage_type,
+ gpointer data)
+{
+ GtkStatusIconPrivate *priv = status_icon->priv;
+
+ g_object_freeze_notify (G_OBJECT (status_icon));
+
+ gtk_status_icon_reset_image_data (status_icon);
+
+ g_object_notify (G_OBJECT (status_icon), "storage-type");
+
+ /* the icon size we pass here doesn't really matter, since
+ * we force a pixel size before doing the actual rendering anyway.
+ */
+ switch (storage_type)
+ {
+ case GTK_IMAGE_PIXBUF:
+ _gtk_icon_helper_set_pixbuf (priv->icon_helper, data);
+ g_object_notify (G_OBJECT (status_icon), "pixbuf");
+ break;
+ case GTK_IMAGE_STOCK:
+ _gtk_icon_helper_set_stock_id (priv->icon_helper, data, GTK_ICON_SIZE_SMALL_TOOLBAR);
+ g_object_notify (G_OBJECT (status_icon), "stock");
+ break;
+ case GTK_IMAGE_ICON_NAME:
+ _gtk_icon_helper_set_icon_name (priv->icon_helper, data, GTK_ICON_SIZE_SMALL_TOOLBAR);
+ g_object_notify (G_OBJECT (status_icon), "icon-name");
+ break;
+ case GTK_IMAGE_GICON:
+ _gtk_icon_helper_set_gicon (priv->icon_helper, data, GTK_ICON_SIZE_SMALL_TOOLBAR);
+ g_object_notify (G_OBJECT (status_icon), "gicon");
+ break;
+ default:
+ g_warning ("Image type %u not handled by GtkStatusIcon", storage_type);
+ }
+
+ g_object_thaw_notify (G_OBJECT (status_icon));
+
+ gtk_status_icon_update_image (status_icon);
+}
+
+/**
+ * gtk_status_icon_set_from_pixbuf:
+ * @status_icon: a #GtkStatusIcon
+ * @pixbuf: (allow-none): a #GdkPixbuf or %NULL
+ *
+ * Makes @status_icon display @pixbuf.
+ * See gtk_status_icon_new_from_pixbuf() for details.
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+void
+gtk_status_icon_set_from_pixbuf (GtkStatusIcon *status_icon,
+ GdkPixbuf *pixbuf)
+{
+ g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
+ g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
+
+ gtk_status_icon_set_image (status_icon, GTK_IMAGE_PIXBUF,
+ (gpointer) pixbuf);
+}
+
+/**
+ * gtk_status_icon_set_from_file:
+ * @status_icon: a #GtkStatusIcon
+ * @filename: (type filename): a filename
+ *
+ * Makes @status_icon display the file @filename.
+ * See gtk_status_icon_new_from_file() for details.
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+void
+gtk_status_icon_set_from_file (GtkStatusIcon *status_icon,
+ const gchar *filename)
+{
+ GdkPixbuf *pixbuf;
+
+ g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
+ g_return_if_fail (filename != NULL);
+
+ pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
+
+ gtk_status_icon_set_from_pixbuf (status_icon, pixbuf);
+
+ if (pixbuf)
+ g_object_unref (pixbuf);
+}
+
+/**
+ * gtk_status_icon_set_from_stock:
+ * @status_icon: a #GtkStatusIcon
+ * @stock_id: a stock icon id
+ *
+ * Makes @status_icon display the stock icon with the id @stock_id.
+ * See gtk_status_icon_new_from_stock() for details.
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.10: Use gtk_status_icon_set_from_icon_name() instead.
+ **/
+void
+gtk_status_icon_set_from_stock (GtkStatusIcon *status_icon,
+ const gchar *stock_id)
+{
+ g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
+ g_return_if_fail (stock_id != NULL);
+
+ gtk_status_icon_set_image (status_icon, GTK_IMAGE_STOCK,
+ (gpointer) stock_id);
+}
+
+/**
+ * gtk_status_icon_set_from_icon_name:
+ * @status_icon: a #GtkStatusIcon
+ * @icon_name: an icon name
+ *
+ * Makes @status_icon display the icon named @icon_name from the
+ * current icon theme.
+ * See gtk_status_icon_new_from_icon_name() for details.
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+void
+gtk_status_icon_set_from_icon_name (GtkStatusIcon *status_icon,
+ const gchar *icon_name)
+{
+ g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
+ g_return_if_fail (icon_name != NULL);
+
+ gtk_status_icon_set_image (status_icon, GTK_IMAGE_ICON_NAME,
+ (gpointer) icon_name);
+}
+
+/**
+ * gtk_status_icon_set_from_gicon:
+ * @status_icon: a #GtkStatusIcon
+ * @icon: a GIcon
+ *
+ * Makes @status_icon display the #GIcon.
+ * See gtk_status_icon_new_from_gicon() for details.
+ *
+ * Since: 2.14
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+void
+gtk_status_icon_set_from_gicon (GtkStatusIcon *status_icon,
+ GIcon *icon)
+{
+ g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
+ g_return_if_fail (icon != NULL);
+
+ gtk_status_icon_set_image (status_icon, GTK_IMAGE_GICON,
+ (gpointer) icon);
+}
+
+/**
+ * gtk_status_icon_get_storage_type:
+ * @status_icon: a #GtkStatusIcon
+ *
+ * Gets the type of representation being used by the #GtkStatusIcon
+ * to store image data. If the #GtkStatusIcon has no image data,
+ * the return value will be %GTK_IMAGE_EMPTY.
+ *
+ * Returns: the image representation being used
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+GtkImageType
+gtk_status_icon_get_storage_type (GtkStatusIcon *status_icon)
+{
+ g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), GTK_IMAGE_EMPTY);
+
+ return _gtk_icon_helper_get_storage_type (status_icon->priv->icon_helper);
+}
+/**
+ * gtk_status_icon_get_pixbuf:
+ * @status_icon: a #GtkStatusIcon
+ *
+ * Gets the #GdkPixbuf being displayed by the #GtkStatusIcon.
+ * The storage type of the status icon must be %GTK_IMAGE_EMPTY or
+ * %GTK_IMAGE_PIXBUF (see gtk_status_icon_get_storage_type()).
+ * The caller of this function does not own a reference to the
+ * returned pixbuf.
+ *
+ * Returns: (transfer none): the displayed pixbuf,
+ * or %NULL if the image is empty.
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+GdkPixbuf *
+gtk_status_icon_get_pixbuf (GtkStatusIcon *status_icon)
+{
+ GtkStatusIconPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
+
+ priv = status_icon->priv;
+
+ return _gtk_icon_helper_peek_pixbuf (priv->icon_helper);
+}
+
+/**
+ * gtk_status_icon_get_stock:
+ * @status_icon: a #GtkStatusIcon
+ *
+ * Gets the id of the stock icon being displayed by the #GtkStatusIcon.
+ * The storage type of the status icon must be %GTK_IMAGE_EMPTY or
+ * %GTK_IMAGE_STOCK (see gtk_status_icon_get_storage_type()).
+ * The returned string is owned by the #GtkStatusIcon and should not
+ * be freed or modified.
+ *
+ * Returns: stock id of the displayed stock icon,
+ * or %NULL if the image is empty.
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.10: Use gtk_status_icon_get_icon_name() instead.
+ **/
+const gchar *
+gtk_status_icon_get_stock (GtkStatusIcon *status_icon)
+{
+ GtkStatusIconPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
+
+ priv = status_icon->priv;
+
+ return _gtk_icon_helper_get_stock_id (priv->icon_helper);
+}
+
+/**
+ * gtk_status_icon_get_icon_name:
+ * @status_icon: a #GtkStatusIcon
+ *
+ * Gets the name of the icon being displayed by the #GtkStatusIcon.
+ * The storage type of the status icon must be %GTK_IMAGE_EMPTY or
+ * %GTK_IMAGE_ICON_NAME (see gtk_status_icon_get_storage_type()).
+ * The returned string is owned by the #GtkStatusIcon and should not
+ * be freed or modified.
+ *
+ * Returns: name of the displayed icon, or %NULL if the image is empty.
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+const gchar *
+gtk_status_icon_get_icon_name (GtkStatusIcon *status_icon)
+{
+ GtkStatusIconPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
+
+ priv = status_icon->priv;
+
+ return _gtk_icon_helper_get_icon_name (priv->icon_helper);
+}
+
+/**
+ * gtk_status_icon_get_gicon:
+ * @status_icon: a #GtkStatusIcon
+ *
+ * Retrieves the #GIcon being displayed by the #GtkStatusIcon.
+ * The storage type of the status icon must be %GTK_IMAGE_EMPTY or
+ * %GTK_IMAGE_GICON (see gtk_status_icon_get_storage_type()).
+ * The caller of this function does not own a reference to the
+ * returned #GIcon.
+ *
+ * If this function fails, @icon is left unchanged;
+ *
+ * Returns: (transfer none): the displayed icon, or %NULL if the image is empty
+ *
+ * Since: 2.14
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+GIcon *
+gtk_status_icon_get_gicon (GtkStatusIcon *status_icon)
+{
+ GtkStatusIconPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
+
+ priv = status_icon->priv;
+
+ return _gtk_icon_helper_peek_gicon (priv->icon_helper);
+}
+
+/**
+ * gtk_status_icon_get_size:
+ * @status_icon: a #GtkStatusIcon
+ *
+ * Gets the size in pixels that is available for the image.
+ * Stock icons and named icons adapt their size automatically
+ * if the size of the notification area changes. For other
+ * storage types, the size-changed signal can be used to
+ * react to size changes.
+ *
+ * Note that the returned size is only meaningful while the
+ * status icon is embedded (see gtk_status_icon_is_embedded()).
+ *
+ * Returns: the size that is available for the image
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+gint
+gtk_status_icon_get_size (GtkStatusIcon *status_icon)
+{
+ g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), 0);
+
+ return status_icon->priv->size;
+}
+
+/**
+ * gtk_status_icon_set_screen:
+ * @status_icon: a #GtkStatusIcon
+ * @screen: a #GdkScreen
+ *
+ * Sets the #GdkScreen where @status_icon is displayed; if
+ * the icon is already mapped, it will be unmapped, and
+ * then remapped on the new screen.
+ *
+ * Since: 2.12
+ *
+ * Deprecated: 3.14: Use notifications
+ */
+void
+gtk_status_icon_set_screen (GtkStatusIcon *status_icon,
+ GdkScreen *screen)
+{
+ g_return_if_fail (GDK_IS_SCREEN (screen));
+
+#ifdef GDK_WINDOWING_X11
+ if (status_icon->priv->tray_icon)
+ gtk_window_set_screen (GTK_WINDOW (status_icon->priv->tray_icon), screen);
+#endif
+}
+
+/**
+ * gtk_status_icon_get_screen:
+ * @status_icon: a #GtkStatusIcon
+ *
+ * Returns the #GdkScreen associated with @status_icon.
+ *
+ * Returns: (transfer none): a #GdkScreen.
+ *
+ * Since: 2.12
+ *
+ * Deprecated: 3.14: Use notifications
+ */
+GdkScreen *
+gtk_status_icon_get_screen (GtkStatusIcon *status_icon)
+{
+ g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
+
+#ifdef GDK_WINDOWING_X11
+ if (status_icon->priv->tray_icon)
+ return gtk_window_get_screen (GTK_WINDOW (status_icon->priv->tray_icon));
+ else
+#endif
+ return gdk_screen_get_default ();
+}
+
+/**
+ * gtk_status_icon_set_visible:
+ * @status_icon: a #GtkStatusIcon
+ * @visible: %TRUE to show the status icon, %FALSE to hide it
+ *
+ * Shows or hides a status icon.
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+void
+gtk_status_icon_set_visible (GtkStatusIcon *status_icon,
+ gboolean visible)
+{
+ GtkStatusIconPrivate *priv;
+
+ g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
+
+ priv = status_icon->priv;
+
+ visible = visible != FALSE;
+
+ if (priv->visible != visible)
+ {
+ priv->visible = visible;
+
+#ifdef GDK_WINDOWING_X11
+ if (priv->tray_icon)
+ {
+ if (visible)
+ gtk_widget_show (priv->tray_icon);
+ else if (gtk_widget_get_realized (priv->tray_icon))
+ {
+ gtk_widget_hide (priv->tray_icon);
+ gtk_widget_unrealize (priv->tray_icon);
+ }
+ }
+#endif
+#ifdef GDK_WINDOWING_WIN32
+ if (priv->nid.hWnd != NULL)
+ {
+ if (visible)
+ Shell_NotifyIconW (NIM_ADD, &priv->nid);
+ else
+ Shell_NotifyIconW (NIM_DELETE, &priv->nid);
+ }
+#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ QUARTZ_POOL_ALLOC;
+ [priv->status_item setVisible:visible];
+ QUARTZ_POOL_RELEASE;
+#endif
+ g_object_notify (G_OBJECT (status_icon), "visible");
+ }
+}
+
+/**
+ * gtk_status_icon_get_visible:
+ * @status_icon: a #GtkStatusIcon
+ *
+ * Returns whether the status icon is visible or not.
+ * Note that being visible does not guarantee that
+ * the user can actually see the icon, see also
+ * gtk_status_icon_is_embedded().
+ *
+ * Returns: %TRUE if the status icon is visible
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+gboolean
+gtk_status_icon_get_visible (GtkStatusIcon *status_icon)
+{
+ g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), FALSE);
+
+ return status_icon->priv->visible;
+}
+
+/**
+ * gtk_status_icon_is_embedded:
+ * @status_icon: a #GtkStatusIcon
+ *
+ * Returns whether the status icon is embedded in a notification
+ * area.
+ *
+ * Returns: %TRUE if the status icon is embedded in
+ * a notification area.
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+gboolean
+gtk_status_icon_is_embedded (GtkStatusIcon *status_icon)
+{
+ g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), FALSE);
+
+#ifdef GDK_WINDOWING_X11
+ if (status_icon->priv->tray_icon &&
+ gtk_plug_get_embedded (GTK_PLUG (status_icon->priv->tray_icon)))
+ return TRUE;
+ else
+ return FALSE;
+#endif
+#ifdef GDK_WINDOWING_WIN32
+ return TRUE;
+#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ return TRUE;
+#endif
+}
+
+/**
+ * gtk_status_icon_position_menu:
+ * @menu: the #GtkMenu
+ * @x: (out): return location for the x position
+ * @y: (out): return location for the y position
+ * @push_in: (out): whether the first menu item should be offset
+ * (pushed in) to be aligned with the menu popup position
+ * (only useful for GtkOptionMenu).
+ * @user_data: (type GtkStatusIcon): the status icon to position the menu on
+ *
+ * Menu positioning function to use with gtk_menu_popup()
+ * to position @menu aligned to the status icon @user_data.
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.14: Use notifications
+ **/
+void
+gtk_status_icon_position_menu (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gboolean *push_in,
+ gpointer user_data)
+{
+#ifdef GDK_WINDOWING_X11
+ GtkStatusIcon *status_icon = GTK_STATUS_ICON (user_data);
+ GtkStatusIconPrivate *priv = status_icon->priv;
+ GtkAllocation allocation;
+ GtkTrayIcon *tray_icon;
+ GtkWidget *widget;
+ GdkScreen *screen;
+ GtkTextDirection direction;
+ GtkRequisition menu_req;
+ GdkRectangle monitor;
+ GdkWindow *window;
+ gint monitor_num, height, width, xoffset, yoffset;
+
+ g_return_if_fail (GTK_IS_MENU (menu));
+ g_return_if_fail (GTK_IS_STATUS_ICON (user_data));
+
+ if (priv->tray_icon == NULL)
+ {
+ *x = 0;
+ *y = 0;
+ return;
+ }
+
+ tray_icon = GTK_TRAY_ICON (priv->tray_icon);
+ widget = priv->tray_icon;
+
+ direction = gtk_widget_get_direction (widget);
+
+ screen = gtk_widget_get_screen (widget);
+ gtk_menu_set_screen (menu, screen);
+
+ window = gtk_widget_get_window (widget);
+ monitor_num = gdk_screen_get_monitor_at_window (screen, window);
+ if (monitor_num < 0)
+ monitor_num = 0;
+ gtk_menu_set_monitor (menu, monitor_num);
+
+ gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
+
+ gdk_window_get_origin (window, x, y);
+
+ menu_req.width = gtk_widget_get_allocated_width (GTK_WIDGET (menu));
+ menu_req.height = gtk_widget_get_allocated_height (GTK_WIDGET (menu));
+
+ gtk_widget_get_allocation (widget, &allocation);
+ if (_gtk_tray_icon_get_orientation (tray_icon) == GTK_ORIENTATION_VERTICAL)
+ {
+ width = 0;
+ height = allocation.height;
+ xoffset = allocation.width;
+ yoffset = 0;
+ }
+ else
+ {
+ width = allocation.width;
+ height = 0;
+ xoffset = 0;
+ yoffset = allocation.height;
+ }
+
+ if (direction == GTK_TEXT_DIR_RTL)
+ {
+ if ((*x - (menu_req.width - width)) >= monitor.x)
+ *x -= menu_req.width - width;
+ else if ((*x + xoffset + menu_req.width) < (monitor.x + monitor.width))
+ *x += xoffset;
+ else if ((monitor.x + monitor.width - (*x + xoffset)) < *x)
+ *x -= menu_req.width - width;
+ else
+ *x += xoffset;
+ }
+ else
+ {
+ if ((*x + xoffset + menu_req.width) < (monitor.x + monitor.width))
+ *x += xoffset;
+ else if ((*x - (menu_req.width - width)) >= monitor.x)
+ *x -= menu_req.width - width;
+ else if ((monitor.x + monitor.width - (*x + xoffset)) > *x)
+ *x += xoffset;
+ else
+ *x -= menu_req.width - width;
+ }
+
+ if ((*y + yoffset + menu_req.height) < (monitor.y + monitor.height))
+ *y += yoffset;
+ else if ((*y - (menu_req.height - height)) >= monitor.y)
+ *y -= menu_req.height - height;
+ else if (monitor.y + monitor.height - (*y + yoffset) > *y)
+ *y += yoffset;
+ else
+ *y -= menu_req.height - height;
+
+ *push_in = FALSE;
+#endif /* GDK_WINDOWING_X11 */
+
+#ifdef GDK_WINDOWING_WIN32
+ GtkStatusIcon *status_icon;
+ GtkStatusIconPrivate *priv;
+ GtkRequisition menu_req;
+
+ g_return_if_fail (GTK_IS_MENU (menu));
+ g_return_if_fail (GTK_IS_STATUS_ICON (user_data));
+
+ status_icon = GTK_STATUS_ICON (user_data);
+ priv = status_icon->priv;
+
+ gtk_widget_get_preferred_size (GTK_WIDGET (menu), &menu_req, NULL);
+
+ *x = priv->last_click_x;
+ *y = priv->taskbar_top - menu_req.height;
+
+ *push_in = TRUE;
+#endif
+}
+
+/**
+ * gtk_status_icon_get_geometry:
+ * @status_icon: a #GtkStatusIcon
+ * @screen: (out) (transfer none) (allow-none): return location for
+ * the screen, or %NULL if the information is not needed
+ * @area: (out) (allow-none): return location for the area occupied by
+ * the status icon, or %NULL
+ * @orientation: (out) (allow-none): return location for the
+ * orientation of the panel in which the status icon is embedded,
+ * or %NULL. A panel at the top or bottom of the screen is
+ * horizontal, a panel at the left or right is vertical.
+ *
+ * Obtains information about the location of the status icon
+ * on screen. This information can be used to e.g. position
+ * popups like notification bubbles.
+ *
+ * See gtk_status_icon_position_menu() for a more convenient
+ * alternative for positioning menus.
+ *
+ * Note that some platforms do not allow GTK+ to provide
+ * this information, and even on platforms that do allow it,
+ * the information is not reliable unless the status icon
+ * is embedded in a notification area, see
+ * gtk_status_icon_is_embedded().
+ *
+ * Returns: %TRUE if the location information has
+ * been filled in
+ *
+ * Since: 2.10
+ *
+ * Deprecated: 3.14: Use notifications
+ */
+gboolean
+gtk_status_icon_get_geometry (GtkStatusIcon *status_icon,
+ GdkScreen **screen,
+ GdkRectangle *area,
+ GtkOrientation *orientation)
+{
+#ifdef GDK_WINDOWING_X11
+ GtkStatusIconPrivate *priv = status_icon->priv;
+ GtkAllocation allocation;
+ GtkWidget *widget;
+ gint x, y;
+
+ g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), FALSE);
+
+ if (priv->tray_icon == NULL)
+ return FALSE;
+
+ widget = priv->tray_icon;
+
+ if (screen)
+ *screen = gtk_widget_get_screen (widget);
+
+ if (area)
+ {
+ gdk_window_get_origin (gtk_widget_get_window (widget),
+ &x, &y);
+
+ gtk_widget_get_allocation (widget, &allocation);
+ area->x = x;
+ area->y = y;
+ area->width = allocation.width;
+ area->height = allocation.height;
+ }
+
+ if (orientation)
+ *orientation = _gtk_tray_icon_get_orientation (GTK_TRAY_ICON (widget));
+
+ return TRUE;
+#else
+ return FALSE;
+#endif /* GDK_WINDOWING_X11 */
+}
+
+/**
+ * gtk_status_icon_set_has_tooltip:
+ * @status_icon: a #GtkStatusIcon
+ * @has_tooltip: whether or not @status_icon has a tooltip
+ *
+ * Sets the has-tooltip property on @status_icon to @has_tooltip.
+ * See #GtkStatusIcon:has-tooltip for more information.
+ *
+ * Since: 2.16
+ *
+ * Deprecated: 3.14: Use notifications
+ */
+void
+gtk_status_icon_set_has_tooltip (GtkStatusIcon *status_icon,
+ gboolean has_tooltip)
+{
+ GtkStatusIconPrivate *priv;
+ gboolean changed = FALSE;
+
+ g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
+
+ priv = status_icon->priv;
+
+#ifdef GDK_WINDOWING_X11
+ if (priv->tray_icon)
+ {
+ if (gtk_widget_get_has_tooltip (priv->tray_icon) != has_tooltip)
+ {
+ gtk_widget_set_has_tooltip (priv->tray_icon, has_tooltip);
+ changed = TRUE;
+ }
+ }
+#endif
+#ifdef GDK_WINDOWING_WIN32
+ changed = TRUE;
+ if (!has_tooltip && priv->tooltip_text)
+ gtk_status_icon_set_tooltip_text (status_icon, NULL);
+#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ changed = TRUE;
+ if (!has_tooltip && priv->tooltip_text)
+ gtk_status_icon_set_tooltip_text (status_icon, NULL);
+#endif
+
+ if (changed)
+ g_object_notify (G_OBJECT (status_icon), "has-tooltip");
+}
+
+/**
+ * gtk_status_icon_get_has_tooltip:
+ * @status_icon: a #GtkStatusIcon
+ *
+ * Returns the current value of the has-tooltip property.
+ * See #GtkStatusIcon:has-tooltip for more information.
+ *
+ * Returns: current value of has-tooltip on @status_icon.
+ *
+ * Since: 2.16
+ *
+ * Deprecated: 3.14: Use notifications
+ */
+gboolean
+gtk_status_icon_get_has_tooltip (GtkStatusIcon *status_icon)
+{
+ GtkStatusIconPrivate *priv;
+ gboolean has_tooltip = FALSE;
+
+ g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), FALSE);
+
+ priv = status_icon->priv;
+
+#ifdef GDK_WINDOWING_X11
+ if (priv->tray_icon)
+ has_tooltip = gtk_widget_get_has_tooltip (priv->tray_icon);
+#endif
+#ifdef GDK_WINDOWING_WIN32
+ has_tooltip = (priv->tooltip_text != NULL);
+#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ has_tooltip = (priv->tooltip_text != NULL);
+#endif
+
+ return has_tooltip;
+}
+
+/**
+ * gtk_status_icon_set_tooltip_text:
+ * @status_icon: a #GtkStatusIcon
+ * @text: the contents of the tooltip for @status_icon
+ *
+ * Sets @text as the contents of the tooltip.
+ *
+ * This function will take care of setting #GtkStatusIcon:has-tooltip to
+ * %TRUE and of the default handler for the #GtkStatusIcon::query-tooltip
+ * signal.
+ *
+ * See also the #GtkStatusIcon:tooltip-text property and
+ * gtk_tooltip_set_text().
+ *
+ * Since: 2.16
+ *
+ * Deprecated: 3.14: Use notifications
+ */
+void
+gtk_status_icon_set_tooltip_text (GtkStatusIcon *status_icon,
+ const gchar *text)
+{
+ GtkStatusIconPrivate *priv;
+
+ g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
+
+ priv = status_icon->priv;
+
+#ifdef GDK_WINDOWING_X11
+ if (priv->tray_icon)
+ gtk_widget_set_tooltip_text (priv->tray_icon, text);
+#endif
+#ifdef GDK_WINDOWING_WIN32
+ if (text == NULL)
+ priv->nid.uFlags &= ~NIF_TIP;
+ else
+ {
+ WCHAR *wcs = g_utf8_to_utf16 (text, -1, NULL, NULL, NULL);
+
+ priv->nid.uFlags |= NIF_TIP;
+ wcsncpy (priv->nid.szTip, wcs, G_N_ELEMENTS (priv->nid.szTip) - 1);
+ priv->nid.szTip[G_N_ELEMENTS (priv->nid.szTip) - 1] = 0;
+ g_free (wcs);
+ }
+ if (priv->nid.hWnd != NULL && priv->visible)
+ if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
+ g_warning (G_STRLOC ": Shell_NotifyIconW(NIM_MODIFY) failed");
+
+ g_free (priv->tooltip_text);
+ priv->tooltip_text = g_strdup (text);
+#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ QUARTZ_POOL_ALLOC;
+ [priv->status_item setToolTip:text];
+ QUARTZ_POOL_RELEASE;
+
+ g_free (priv->tooltip_text);
+ priv->tooltip_text = g_strdup (text);
+#endif
+}
+
+/**
+ * gtk_status_icon_get_tooltip_text:
+ * @status_icon: a #GtkStatusIcon
+ *
+ * Gets the contents of the tooltip for @status_icon.
+ *
+ * Returns: the tooltip text, or %NULL. You should free the
+ * returned string with g_free() when done.
+ *
+ * Since: 2.16
+ *
+ * Deprecated: 3.14: Use notifications
+ */
+gchar *
+gtk_status_icon_get_tooltip_text (GtkStatusIcon *status_icon)
+{
+ GtkStatusIconPrivate *priv;
+ gchar *tooltip_text = NULL;
+
+ g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
+
+ priv = status_icon->priv;
+
+#ifdef GDK_WINDOWING_X11
+ if (priv->tray_icon)
+ tooltip_text = gtk_widget_get_tooltip_text (priv->tray_icon);
+#endif
+#ifdef GDK_WINDOWING_WIN32
+ if (priv->tooltip_text)
+ tooltip_text = g_strdup (priv->tooltip_text);
+#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ if (priv->tooltip_text)
+ tooltip_text = g_strdup (priv->tooltip_text);
+#endif
+
+ return tooltip_text;
+}
+
+/**
+ * gtk_status_icon_set_tooltip_markup:
+ * @status_icon: a #GtkStatusIcon
+ * @markup: (allow-none): the contents of the tooltip for @status_icon, or %NULL
+ *
+ * Sets @markup as the contents of the tooltip, which is marked up with
+ * the [Pango text markup language][PangoMarkupFormat].
+ *
+ * This function will take care of setting #GtkStatusIcon:has-tooltip to %TRUE
+ * and of the default handler for the #GtkStatusIcon::query-tooltip signal.
+ *
+ * See also the #GtkStatusIcon:tooltip-markup property and
+ * gtk_tooltip_set_markup().
+ *
+ * Since: 2.16
+ *
+ * Deprecated: 3.14: Use notifications
+ */
+void
+gtk_status_icon_set_tooltip_markup (GtkStatusIcon *status_icon,
+ const gchar *markup)
+{
+#ifdef GDK_WINDOWING_X11
+ GtkStatusIconPrivate *priv;
+#else
+ gchar *text = NULL;
+#endif
+
+ g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
+
+#ifdef GDK_WINDOWING_X11
+ priv = status_icon->priv;
+
+ if (priv->tray_icon)
+ gtk_widget_set_tooltip_markup (priv->tray_icon, markup);
+#endif
+#ifdef GDK_WINDOWING_WIN32
+ if (markup)
+ pango_parse_markup (markup, -1, 0, NULL, &text, NULL, NULL);
+ gtk_status_icon_set_tooltip_text (status_icon, text);
+ g_free (text);
+#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ if (markup)
+ pango_parse_markup (markup, -1, 0, NULL, &text, NULL, NULL);
+ gtk_status_icon_set_tooltip_text (status_icon, text);
+ g_free (text);
+#endif
+}
+
+/**
+ * gtk_status_icon_get_tooltip_markup:
+ * @status_icon: a #GtkStatusIcon
+ *
+ * Gets the contents of the tooltip for @status_icon.
+ *
+ * Returns: the tooltip text, or %NULL. You should free the
+ * returned string with g_free() when done.
+ *
+ * Since: 2.16
+ *
+ * Deprecated: 3.14: Use notifications
+ */
+gchar *
+gtk_status_icon_get_tooltip_markup (GtkStatusIcon *status_icon)
+{
+ GtkStatusIconPrivate *priv;
+ gchar *markup = NULL;
+
+ g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
+
+ priv = status_icon->priv;
+
+#ifdef GDK_WINDOWING_X11
+ if (priv->tray_icon)
+ markup = gtk_widget_get_tooltip_markup (priv->tray_icon);
+#endif
+#ifdef GDK_WINDOWING_WIN32
+ if (priv->tooltip_text)
+ markup = g_markup_escape_text (priv->tooltip_text, -1);
+#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ if (priv->tooltip_text)
+ markup = g_markup_escape_text (priv->tooltip_text, -1);
+#endif
+
+ return markup;
+}
+
+/**
+ * gtk_status_icon_get_x11_window_id:
+ * @status_icon: a #GtkStatusIcon
+ *
+ * This function is only useful on the X11/freedesktop.org platform.
+ * It returns a window ID for the widget in the underlying
+ * status icon implementation. This is useful for the Galago
+ * notification service, which can send a window ID in the protocol
+ * in order for the server to position notification windows
+ * pointing to a status icon reliably.
+ *
+ * This function is not intended for other use cases which are
+ * more likely to be met by one of the non-X11 specific methods, such
+ * as gtk_status_icon_position_menu().
+ *
+ * Returns: An 32 bit unsigned integer identifier for the
+ * underlying X11 Window
+ *
+ * Since: 2.14
+ *
+ * Deprecated: 3.14: Use notifications
+ */
+guint32
+gtk_status_icon_get_x11_window_id (GtkStatusIcon *status_icon)
+{
+#ifdef GDK_WINDOWING_X11
+ if (status_icon->priv->tray_icon)
+ {
+ gtk_widget_realize (GTK_WIDGET (status_icon->priv->tray_icon));
+ return GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (status_icon->priv->tray_icon)));
+ }
+ else
+#endif
+ return 0;
+}
+
+/**
+ * gtk_status_icon_set_title:
+ * @status_icon: a #GtkStatusIcon
+ * @title: the title
+ *
+ * Sets the title of this tray icon.
+ * This should be a short, human-readable, localized string
+ * describing the tray icon. It may be used by tools like screen
+ * readers to render the tray icon.
+ *
+ * Since: 2.18
+ *
+ * Deprecated: 3.14: Use notifications
+ */
+void
+gtk_status_icon_set_title (GtkStatusIcon *status_icon,
+ const gchar *title)
+{
+ GtkStatusIconPrivate *priv;
+
+ g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
+
+ priv = status_icon->priv;
+
+#ifdef GDK_WINDOWING_X11
+ if (priv->tray_icon)
+ gtk_window_set_title (GTK_WINDOW (priv->tray_icon), title);
+#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ g_free (priv->title);
+ priv->title = g_strdup (title);
+#endif
+#ifdef GDK_WINDOWING_WIN32
+ g_free (priv->title);
+ priv->title = g_strdup (title);
+#endif
+
+ g_object_notify (G_OBJECT (status_icon), "title");
+}
+
+/**
+ * gtk_status_icon_get_title:
+ * @status_icon: a #GtkStatusIcon
+ *
+ * Gets the title of this tray icon. See gtk_status_icon_set_title().
+ *
+ * Returns: the title of the status icon
+ *
+ * Since: 2.18
+ *
+ * Deprecated: 3.14: Use notifications
+ */
+const gchar *
+gtk_status_icon_get_title (GtkStatusIcon *status_icon)
+{
+ GtkStatusIconPrivate *priv;
+ const gchar *title = NULL;
+
+ g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
+
+ priv = status_icon->priv;
+
+#ifdef GDK_WINDOWING_X11
+ if (priv->tray_icon)
+ title = gtk_window_get_title (GTK_WINDOW (priv->tray_icon));
+#endif
+#ifdef GDK_WINDOWING_QUARTZ
+ title = priv->title;
+#endif
+#ifdef GDK_WINDOWING_WIN32
+ title = priv->title;
+#endif
+
+ return title;
+}
+
+
+/**
+ * gtk_status_icon_set_name:
+ * @status_icon: a #GtkStatusIcon
+ * @name: the name
+ *
+ * Sets the name of this tray icon.
+ * This should be a string identifying this icon. It is may be
+ * used for sorting the icons in the tray and will not be shown to
+ * the user.
+ *
+ * Since: 2.20
+ *
+ * Deprecated: 3.14: Use notifications
+ */
+void
+gtk_status_icon_set_name (GtkStatusIcon *status_icon,
+ const gchar *name)
+{
+#ifdef GDK_WINDOWING_X11
+ GtkStatusIconPrivate *priv;
+#endif
+
+ g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
+
+#ifdef GDK_WINDOWING_X11
+ priv = status_icon->priv;
+
+ if (priv->tray_icon)
+ {
+ if (gtk_widget_get_realized (priv->tray_icon))
+ {
+ /* gtk_window_set_wmclass() only operates on non-realized windows,
+ * so temporarily unrealize the tray here
+ */
+ gtk_widget_hide (priv->tray_icon);
+ gtk_widget_unrealize (priv->tray_icon);
+ gtk_window_set_wmclass (GTK_WINDOW (priv->tray_icon), name, name);
+ gtk_widget_show (priv->tray_icon);
+ }
+ else
+ gtk_window_set_wmclass (GTK_WINDOW (priv->tray_icon), name, name);
+ }
+#endif
+}
--- /dev/null
+/* gtkstatusicon.h:
+ *
+ * Copyright (C) 2003 Sun Microsystems, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Mark McLoughlin <mark@skynet.ie>
+ */
+
+#ifndef __GTK_STATUS_ICON_H__
+#define __GTK_STATUS_ICON_H__
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#include <gtk/gtkimage.h>
+#include <gtk/gtkmenu.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_STATUS_ICON (gtk_status_icon_get_type ())
+#define GTK_STATUS_ICON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_STATUS_ICON, GtkStatusIcon))
+#define GTK_STATUS_ICON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_STATUS_ICON, GtkStatusIconClass))
+#define GTK_IS_STATUS_ICON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_STATUS_ICON))
+#define GTK_IS_STATUS_ICON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTK_TYPE_STATUS_ICON))
+#define GTK_STATUS_ICON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_STATUS_ICON, GtkStatusIconClass))
+
+typedef struct _GtkStatusIcon GtkStatusIcon;
+typedef struct _GtkStatusIconClass GtkStatusIconClass;
+typedef struct _GtkStatusIconPrivate GtkStatusIconPrivate;
+
+struct _GtkStatusIcon
+{
+ GObject parent_instance;
+
+ GtkStatusIconPrivate *priv;
+};
+
+struct _GtkStatusIconClass
+{
+ GObjectClass parent_class;
+
+ void (* activate) (GtkStatusIcon *status_icon);
+ void (* popup_menu) (GtkStatusIcon *status_icon,
+ guint button,
+ guint32 activate_time);
+ gboolean (* size_changed) (GtkStatusIcon *status_icon,
+ gint size);
+ gboolean (* button_press_event) (GtkStatusIcon *status_icon,
+ GdkEventButton *event);
+ gboolean (* button_release_event) (GtkStatusIcon *status_icon,
+ GdkEventButton *event);
+ gboolean (* scroll_event) (GtkStatusIcon *status_icon,
+ GdkEventScroll *event);
+ gboolean (* query_tooltip) (GtkStatusIcon *status_icon,
+ gint x,
+ gint y,
+ gboolean keyboard_mode,
+ GtkTooltip *tooltip);
+
+ void (*__gtk_reserved1);
+ void (*__gtk_reserved2);
+ void (*__gtk_reserved3);
+ void (*__gtk_reserved4);
+};
+
+GDK_AVAILABLE_IN_ALL
+GType gtk_status_icon_get_type (void) G_GNUC_CONST;
+
+GDK_DEPRECATED_IN_3_14
+GtkStatusIcon *gtk_status_icon_new (void);
+GDK_DEPRECATED_IN_3_14
+GtkStatusIcon *gtk_status_icon_new_from_pixbuf (GdkPixbuf *pixbuf);
+GDK_DEPRECATED_IN_3_14
+GtkStatusIcon *gtk_status_icon_new_from_file (const gchar *filename);
+GDK_DEPRECATED_IN_3_10_FOR(gtk_status_icon_new_from_icon_name)
+GtkStatusIcon *gtk_status_icon_new_from_stock (const gchar *stock_id);
+GDK_DEPRECATED_IN_3_14
+GtkStatusIcon *gtk_status_icon_new_from_icon_name (const gchar *icon_name);
+GDK_DEPRECATED_IN_3_14
+GtkStatusIcon *gtk_status_icon_new_from_gicon (GIcon *icon);
+
+GDK_DEPRECATED_IN_3_14
+void gtk_status_icon_set_from_pixbuf (GtkStatusIcon *status_icon,
+ GdkPixbuf *pixbuf);
+GDK_DEPRECATED_IN_3_14
+void gtk_status_icon_set_from_file (GtkStatusIcon *status_icon,
+ const gchar *filename);
+GDK_DEPRECATED_IN_3_10_FOR(gtk_status_icon_set_from_icon_name)
+void gtk_status_icon_set_from_stock (GtkStatusIcon *status_icon,
+ const gchar *stock_id);
+GDK_DEPRECATED_IN_3_14
+void gtk_status_icon_set_from_icon_name (GtkStatusIcon *status_icon,
+ const gchar *icon_name);
+GDK_DEPRECATED_IN_3_14
+void gtk_status_icon_set_from_gicon (GtkStatusIcon *status_icon,
+ GIcon *icon);
+
+GDK_DEPRECATED_IN_3_14
+GtkImageType gtk_status_icon_get_storage_type (GtkStatusIcon *status_icon);
+
+GDK_DEPRECATED_IN_3_14
+GdkPixbuf *gtk_status_icon_get_pixbuf (GtkStatusIcon *status_icon);
+GDK_DEPRECATED_IN_3_10_FOR(gtk_status_icon_get_icon_name)
+const gchar * gtk_status_icon_get_stock (GtkStatusIcon *status_icon);
+GDK_DEPRECATED_IN_3_14
+const gchar * gtk_status_icon_get_icon_name (GtkStatusIcon *status_icon);
+GDK_DEPRECATED_IN_3_14
+GIcon *gtk_status_icon_get_gicon (GtkStatusIcon *status_icon);
+
+GDK_DEPRECATED_IN_3_14
+gint gtk_status_icon_get_size (GtkStatusIcon *status_icon);
+
+GDK_DEPRECATED_IN_3_14
+void gtk_status_icon_set_screen (GtkStatusIcon *status_icon,
+ GdkScreen *screen);
+GDK_DEPRECATED_IN_3_14
+GdkScreen *gtk_status_icon_get_screen (GtkStatusIcon *status_icon);
+
+GDK_DEPRECATED_IN_3_14
+void gtk_status_icon_set_has_tooltip (GtkStatusIcon *status_icon,
+ gboolean has_tooltip);
+GDK_DEPRECATED_IN_3_14
+void gtk_status_icon_set_tooltip_text (GtkStatusIcon *status_icon,
+ const gchar *text);
+GDK_DEPRECATED_IN_3_14
+void gtk_status_icon_set_tooltip_markup (GtkStatusIcon *status_icon,
+ const gchar *markup);
+GDK_DEPRECATED_IN_3_14
+void gtk_status_icon_set_title (GtkStatusIcon *status_icon,
+ const gchar *title);
+GDK_DEPRECATED_IN_3_14
+const gchar * gtk_status_icon_get_title (GtkStatusIcon *status_icon);
+GDK_DEPRECATED_IN_3_14
+void gtk_status_icon_set_name (GtkStatusIcon *status_icon,
+ const gchar *name);
+GDK_DEPRECATED_IN_3_14
+void gtk_status_icon_set_visible (GtkStatusIcon *status_icon,
+ gboolean visible);
+GDK_DEPRECATED_IN_3_14
+gboolean gtk_status_icon_get_visible (GtkStatusIcon *status_icon);
+
+GDK_DEPRECATED_IN_3_14
+gboolean gtk_status_icon_is_embedded (GtkStatusIcon *status_icon);
+
+GDK_DEPRECATED_IN_3_14
+void gtk_status_icon_position_menu (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gboolean *push_in,
+ gpointer user_data);
+GDK_DEPRECATED_IN_3_14
+gboolean gtk_status_icon_get_geometry (GtkStatusIcon *status_icon,
+ GdkScreen **screen,
+ GdkRectangle *area,
+ GtkOrientation *orientation);
+GDK_DEPRECATED_IN_3_14
+gboolean gtk_status_icon_get_has_tooltip (GtkStatusIcon *status_icon);
+GDK_DEPRECATED_IN_3_14
+gchar *gtk_status_icon_get_tooltip_text (GtkStatusIcon *status_icon);
+GDK_DEPRECATED_IN_3_14
+gchar *gtk_status_icon_get_tooltip_markup (GtkStatusIcon *status_icon);
+
+GDK_DEPRECATED_IN_3_14
+guint32 gtk_status_icon_get_x11_window_id (GtkStatusIcon *status_icon);
+
+G_END_DECLS
+
+#endif /* __GTK_STATUS_ICON_H__ */
--- /dev/null
+/* gtktrayicon.c
+ * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This is an implementation of the freedesktop.org “system tray” spec,
+ * http://www.freedesktop.org/wiki/Standards/systemtray-spec
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include <string.h>
+
+#include "x11/gdkx.h"
+#include <X11/Xatom.h>
+#include <cairo-xlib.h>
+
+#include "gtkintl.h"
+#include "gtkprivate.h"
+#include "gtktrayicon.h"
+#include "gtktestutils.h"
+#include "gtkdebug.h"
+#include "gtktypebuiltins.h"
+
+#define SYSTEM_TRAY_REQUEST_DOCK 0
+#define SYSTEM_TRAY_BEGIN_MESSAGE 1
+#define SYSTEM_TRAY_CANCEL_MESSAGE 2
+
+#define SYSTEM_TRAY_ORIENTATION_HORZ 0
+#define SYSTEM_TRAY_ORIENTATION_VERT 1
+
+enum {
+ PROP_0,
+ PROP_ORIENTATION,
+ PROP_FG_COLOR,
+ PROP_ERROR_COLOR,
+ PROP_WARNING_COLOR,
+ PROP_SUCCESS_COLOR,
+ PROP_PADDING,
+ PROP_ICON_SIZE
+};
+
+struct _GtkTrayIconPrivate
+{
+ guint stamp;
+
+ Atom selection_atom;
+ Atom manager_atom;
+ Atom system_tray_opcode_atom;
+ Atom orientation_atom;
+ Atom visual_atom;
+ Atom colors_atom;
+ Atom padding_atom;
+ Atom icon_size_atom;
+ Window manager_window;
+ GdkVisual *manager_visual;
+ gboolean manager_visual_rgba;
+
+ GtkOrientation orientation;
+ GdkRGBA fg_color;
+ GdkRGBA error_color;
+ GdkRGBA warning_color;
+ GdkRGBA success_color;
+ gint padding;
+ gint icon_size;
+};
+
+static void gtk_tray_icon_constructed (GObject *object);
+static void gtk_tray_icon_dispose (GObject *object);
+
+static void gtk_tray_icon_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void gtk_tray_icon_realize (GtkWidget *widget);
+static void gtk_tray_icon_style_updated (GtkWidget *widget);
+static gboolean gtk_tray_icon_delete (GtkWidget *widget,
+ GdkEventAny *event);
+static gboolean gtk_tray_icon_draw (GtkWidget *widget,
+ cairo_t *cr);
+
+static void gtk_tray_icon_clear_manager_window (GtkTrayIcon *icon);
+static void gtk_tray_icon_update_manager_window (GtkTrayIcon *icon);
+static void gtk_tray_icon_manager_window_destroyed (GtkTrayIcon *icon);
+
+static GdkFilterReturn gtk_tray_icon_manager_filter (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer user_data);
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtkTrayIcon, gtk_tray_icon, GTK_TYPE_PLUG)
+
+static void
+gtk_tray_icon_class_init (GtkTrayIconClass *class)
+{
+ GObjectClass *gobject_class = (GObjectClass *)class;
+ GtkWidgetClass *widget_class = (GtkWidgetClass *)class;
+
+ gobject_class->get_property = gtk_tray_icon_get_property;
+ gobject_class->constructed = gtk_tray_icon_constructed;
+ gobject_class->dispose = gtk_tray_icon_dispose;
+
+ widget_class->realize = gtk_tray_icon_realize;
+ widget_class->style_updated = gtk_tray_icon_style_updated;
+ widget_class->delete_event = gtk_tray_icon_delete;
+ widget_class->draw = gtk_tray_icon_draw;
+
+ g_object_class_install_property (gobject_class,
+ PROP_ORIENTATION,
+ g_param_spec_enum ("orientation",
+ P_("Orientation"),
+ P_("The orientation of the tray"),
+ GTK_TYPE_ORIENTATION,
+ GTK_ORIENTATION_HORIZONTAL,
+ GTK_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_FG_COLOR,
+ g_param_spec_boxed ("fg-color",
+ P_("Foreground color"),
+ P_("Foreground color for symbolic icons"),
+ GDK_TYPE_RGBA,
+ GTK_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_ERROR_COLOR,
+ g_param_spec_boxed ("error-color",
+ P_("Error color"),
+ P_("Error color for symbolic icons"),
+ GDK_TYPE_RGBA,
+ GTK_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_WARNING_COLOR,
+ g_param_spec_boxed ("warning-color",
+ P_("Warning color"),
+ P_("Warning color for symbolic icons"),
+ GDK_TYPE_RGBA,
+ GTK_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_SUCCESS_COLOR,
+ g_param_spec_boxed ("success-color",
+ P_("Success color"),
+ P_("Success color for symbolic icons"),
+ GDK_TYPE_RGBA,
+ GTK_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_PADDING,
+ g_param_spec_int ("padding",
+ P_("Padding"),
+ P_("Padding that should be put around icons in the tray"),
+ 0,
+ G_MAXINT,
+ 0,
+ GTK_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_ICON_SIZE,
+ g_param_spec_int ("icon-size",
+ P_("Icon Size"),
+ P_("The pixel size that icons should be forced to, or zero"),
+ 0,
+ G_MAXINT,
+ 0,
+ GTK_PARAM_READABLE));
+}
+
+static void
+gtk_tray_icon_init (GtkTrayIcon *icon)
+{
+ icon->priv = gtk_tray_icon_get_instance_private (icon);
+ icon->priv->stamp = 1;
+ icon->priv->orientation = GTK_ORIENTATION_HORIZONTAL;
+ icon->priv->fg_color.red = 0.0;
+ icon->priv->fg_color.green = 0.0;
+ icon->priv->fg_color.blue = 0.0;
+ icon->priv->fg_color.alpha = 1.0;
+ icon->priv->error_color.red = 0.7968;
+ icon->priv->error_color.green = 0.0;
+ icon->priv->error_color.blue = 0.0;
+ icon->priv->error_color.alpha = 1.0;
+ icon->priv->warning_color.red = 0.9570;
+ icon->priv->warning_color.green = 0.4726;
+ icon->priv->warning_color.blue = 0.2421;
+ icon->priv->warning_color.alpha = 1.0;
+ icon->priv->success_color.red = 0.3047;
+ icon->priv->success_color.green = 0.6016;
+ icon->priv->success_color.blue = 0.0234;
+ icon->priv->success_color.alpha = 1.0;
+ icon->priv->padding = 0;
+ icon->priv->icon_size = 0;
+
+ gtk_widget_set_app_paintable (GTK_WIDGET (icon), TRUE);
+ gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK);
+}
+
+static void
+gtk_tray_icon_constructed (GObject *object)
+{
+ /* Do setup that depends on the screen; screen has been set at this point */
+
+ GtkTrayIcon *icon = GTK_TRAY_ICON (object);
+ GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (object));
+ GdkWindow *root_window = gdk_screen_get_root_window (screen);
+ GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (object));
+ Display *xdisplay = gdk_x11_display_get_xdisplay (display);
+ char buffer[256];
+
+ g_snprintf (buffer, sizeof (buffer),
+ "_NET_SYSTEM_TRAY_S%d",
+ gdk_screen_get_number (screen));
+
+ icon->priv->selection_atom = XInternAtom (xdisplay, buffer, False);
+
+ icon->priv->manager_atom = XInternAtom (xdisplay, "MANAGER", False);
+
+ icon->priv->system_tray_opcode_atom = XInternAtom (xdisplay,
+ "_NET_SYSTEM_TRAY_OPCODE",
+ False);
+
+ icon->priv->orientation_atom = XInternAtom (xdisplay,
+ "_NET_SYSTEM_TRAY_ORIENTATION",
+ False);
+
+ icon->priv->visual_atom = XInternAtom (xdisplay,
+ "_NET_SYSTEM_TRAY_VISUAL",
+ False);
+
+ icon->priv->colors_atom = XInternAtom (xdisplay,
+ "_NET_SYSTEM_TRAY_COLORS",
+ False);
+
+ icon->priv->padding_atom = XInternAtom (xdisplay,
+ "_NET_SYSTEM_TRAY_PADDING",
+ False);
+
+ icon->priv->icon_size_atom = XInternAtom (xdisplay,
+ "_NET_SYSTEM_TRAY_ICON_SIZE",
+ False);
+
+ /* Add a root window filter so that we get changes on MANAGER */
+ gdk_window_add_filter (root_window,
+ gtk_tray_icon_manager_filter, icon);
+
+ gtk_tray_icon_update_manager_window (icon);
+}
+
+static void
+gtk_tray_icon_clear_manager_window (GtkTrayIcon *icon)
+{
+ GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (icon));
+
+ if (icon->priv->manager_window != None)
+ {
+ GdkWindow *gdkwin;
+
+ gdkwin = gdk_x11_window_lookup_for_display (display,
+ icon->priv->manager_window);
+
+ gdk_window_remove_filter (gdkwin, gtk_tray_icon_manager_filter, icon);
+
+ icon->priv->manager_window = None;
+ icon->priv->manager_visual = NULL;
+ }
+}
+
+static void
+gtk_tray_icon_dispose (GObject *object)
+{
+ GtkTrayIcon *icon = GTK_TRAY_ICON (object);
+ GtkWidget *widget = GTK_WIDGET (object);
+ GdkWindow *root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget));
+
+ gtk_tray_icon_clear_manager_window (icon);
+
+ gdk_window_remove_filter (root_window, gtk_tray_icon_manager_filter, icon);
+
+ G_OBJECT_CLASS (gtk_tray_icon_parent_class)->dispose (object);
+}
+
+static void
+gtk_tray_icon_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkTrayIcon *icon = GTK_TRAY_ICON (object);
+
+ switch (prop_id)
+ {
+ case PROP_ORIENTATION:
+ g_value_set_enum (value, icon->priv->orientation);
+ break;
+ case PROP_FG_COLOR:
+ g_value_set_boxed (value, &icon->priv->fg_color);
+ break;
+ case PROP_ERROR_COLOR:
+ g_value_set_boxed (value, &icon->priv->error_color);
+ break;
+ case PROP_WARNING_COLOR:
+ g_value_set_boxed (value, &icon->priv->warning_color);
+ break;
+ case PROP_SUCCESS_COLOR:
+ g_value_set_boxed (value, &icon->priv->success_color);
+ break;
+ case PROP_PADDING:
+ g_value_set_int (value, icon->priv->padding);
+ break;
+ case PROP_ICON_SIZE:
+ g_value_set_int (value, icon->priv->icon_size);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static gboolean
+gtk_tray_icon_draw (GtkWidget *widget,
+ cairo_t *cr)
+{
+ GtkTrayIcon *icon = GTK_TRAY_ICON (widget);
+ GtkWidget *focus_child;
+ GdkWindow *window;
+ gint border_width;
+ gboolean retval = FALSE;
+ cairo_surface_t *target;
+
+ window = gtk_widget_get_window (widget);
+ target = cairo_get_group_target (cr);
+
+ if (icon->priv->manager_visual_rgba ||
+ cairo_surface_get_type (target) != CAIRO_SURFACE_TYPE_XLIB ||
+ cairo_xlib_surface_get_drawable (target) != GDK_WINDOW_XID (window))
+ {
+ /* Clear to transparent */
+ cairo_set_source_rgba (cr, 0, 0, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_paint (cr);
+ }
+
+ if (GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->draw)
+ retval = GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->draw (widget, cr);
+
+ focus_child = gtk_container_get_focus_child (GTK_CONTAINER (widget));
+ if (focus_child && gtk_widget_has_visible_focus (focus_child))
+ {
+ GtkStyleContext *context;
+
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+ context = gtk_widget_get_style_context (widget);
+
+ gtk_render_focus (context, cr, border_width, border_width,
+ gtk_widget_get_allocated_width (widget) - 2 * border_width,
+ gtk_widget_get_allocated_height (widget) - 2 * border_width);
+ }
+
+ return retval;
+}
+
+static void
+gtk_tray_icon_get_orientation_property (GtkTrayIcon *icon)
+{
+ GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (icon));
+ GdkDisplay *display = gdk_screen_get_display (screen);
+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ Atom type;
+ int format;
+ union {
+ gulong *prop;
+ guchar *prop_ch;
+ } prop = { NULL };
+ gulong nitems;
+ gulong bytes_after;
+ int error, result;
+
+ g_assert (icon->priv->manager_window != None);
+
+ gdk_error_trap_push ();
+ type = None;
+ result = XGetWindowProperty (xdisplay,
+ icon->priv->manager_window,
+ icon->priv->orientation_atom,
+ 0, G_MAXLONG, FALSE,
+ XA_CARDINAL,
+ &type, &format, &nitems,
+ &bytes_after, &(prop.prop_ch));
+ error = gdk_error_trap_pop ();
+
+ if (error || result != Success)
+ return;
+
+ if (type == XA_CARDINAL && nitems == 1 && format == 32)
+ {
+ GtkOrientation orientation;
+
+ orientation = (prop.prop [0] == SYSTEM_TRAY_ORIENTATION_HORZ) ?
+ GTK_ORIENTATION_HORIZONTAL :
+ GTK_ORIENTATION_VERTICAL;
+
+ if (icon->priv->orientation != orientation)
+ {
+ icon->priv->orientation = orientation;
+
+ g_object_notify (G_OBJECT (icon), "orientation");
+ }
+ }
+
+ if (type != None)
+ XFree (prop.prop);
+}
+
+static void
+gtk_tray_icon_get_visual_property (GtkTrayIcon *icon)
+{
+ GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (icon));
+ GdkDisplay *display = gdk_screen_get_display (screen);
+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ Atom type;
+ int format;
+ union {
+ gulong *prop;
+ guchar *prop_ch;
+ } prop = { NULL };
+ gulong nitems;
+ gulong bytes_after;
+ int error, result;
+
+ g_assert (icon->priv->manager_window != None);
+
+ gdk_error_trap_push ();
+ type = None;
+ result = XGetWindowProperty (xdisplay,
+ icon->priv->manager_window,
+ icon->priv->visual_atom,
+ 0, G_MAXLONG, FALSE,
+ XA_VISUALID,
+ &type, &format, &nitems,
+ &bytes_after, &(prop.prop_ch));
+ error = gdk_error_trap_pop ();
+
+ if (!error && result == Success &&
+ type == XA_VISUALID && nitems == 1 && format == 32)
+ {
+ VisualID visual_id;
+ GdkVisual *visual;
+ gint red_prec, green_prec, blue_prec;
+
+ visual_id = prop.prop[0];
+ visual = gdk_x11_screen_lookup_visual (screen, visual_id);
+ gdk_visual_get_red_pixel_details (visual, NULL, NULL, &red_prec);
+ gdk_visual_get_green_pixel_details (visual, NULL, NULL, &green_prec);
+ gdk_visual_get_blue_pixel_details (visual, NULL, NULL, &blue_prec);
+ icon->priv->manager_visual = visual;
+ icon->priv->manager_visual_rgba =
+ (red_prec + blue_prec + green_prec < gdk_visual_get_depth (visual));
+ }
+ else
+ {
+ icon->priv->manager_visual = NULL;
+ icon->priv->manager_visual_rgba = FALSE;
+ }
+
+ if (type != None)
+ XFree (prop.prop);
+}
+
+static void
+gtk_tray_icon_get_colors_property (GtkTrayIcon *icon)
+{
+ GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (icon));
+ GdkDisplay *display = gdk_screen_get_display (screen);
+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ Atom type;
+ int format;
+ union {
+ gulong *prop;
+ guchar *prop_ch;
+ } prop = { NULL };
+ gulong nitems;
+ gulong bytes_after;
+ int error, result;
+
+ g_assert (icon->priv->manager_window != None);
+
+ gdk_error_trap_push ();
+ type = None;
+ result = XGetWindowProperty (xdisplay,
+ icon->priv->manager_window,
+ icon->priv->colors_atom,
+ 0, G_MAXLONG, FALSE,
+ XA_CARDINAL,
+ &type, &format, &nitems,
+ &bytes_after, &(prop.prop_ch));
+ error = gdk_error_trap_pop ();
+
+ if (error || result != Success)
+ return;
+
+ if (type == XA_CARDINAL && nitems == 12 && format == 32)
+ {
+ GdkRGBA color;
+
+ g_object_freeze_notify (G_OBJECT (icon));
+
+ color.red = prop.prop[0] / 65535.0;
+ color.green = prop.prop[1] / 65535.0;
+ color.blue = prop.prop[2] / 65535.0;
+
+ if (!gdk_rgba_equal (&icon->priv->fg_color, &color))
+ {
+ icon->priv->fg_color = color;
+
+ g_object_notify (G_OBJECT (icon), "fg-color");
+ }
+
+ color.red = prop.prop[3] / 65535.0;
+ color.green = prop.prop[4] / 65535.0;
+ color.blue = prop.prop[5] / 65535.0;
+
+ if (!gdk_rgba_equal (&icon->priv->error_color, &color))
+ {
+ icon->priv->error_color = color;
+
+ g_object_notify (G_OBJECT (icon), "error-color");
+ }
+
+ color.red = prop.prop[6] / 65535.0;
+ color.green = prop.prop[7] / 65535.0;
+ color.blue = prop.prop[8] / 65535.0;
+
+ if (!gdk_rgba_equal (&icon->priv->warning_color, &color))
+ {
+ icon->priv->warning_color = color;
+
+ g_object_notify (G_OBJECT (icon), "warning-color");
+ }
+
+ color.red = prop.prop[9] / 65535.0;
+ color.green = prop.prop[10] / 65535.0;
+ color.blue = prop.prop[11] / 65535.0;
+
+ if (!gdk_rgba_equal (&icon->priv->success_color, &color))
+ {
+ icon->priv->success_color = color;
+
+ g_object_notify (G_OBJECT (icon), "success-color");
+ }
+
+ g_object_thaw_notify (G_OBJECT (icon));
+ }
+
+ if (type != None)
+ XFree (prop.prop);
+}
+
+static void
+gtk_tray_icon_get_padding_property (GtkTrayIcon *icon)
+{
+ GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (icon));
+ GdkDisplay *display = gdk_screen_get_display (screen);
+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ Atom type;
+ int format;
+ union {
+ gulong *prop;
+ guchar *prop_ch;
+ } prop = { NULL };
+ gulong nitems;
+ gulong bytes_after;
+ int error, result;
+
+ g_assert (icon->priv->manager_window != None);
+
+ gdk_error_trap_push ();
+ type = None;
+ result = XGetWindowProperty (xdisplay,
+ icon->priv->manager_window,
+ icon->priv->padding_atom,
+ 0, G_MAXLONG, FALSE,
+ XA_CARDINAL,
+ &type, &format, &nitems,
+ &bytes_after, &(prop.prop_ch));
+ error = gdk_error_trap_pop ();
+
+ if (!error && result == Success &&
+ type == XA_CARDINAL && nitems == 1 && format == 32)
+ {
+ gint padding;
+
+ padding = prop.prop[0];
+
+ if (icon->priv->padding != padding)
+ {
+ icon->priv->padding = padding;
+
+ g_object_notify (G_OBJECT (icon), "padding");
+ }
+ }
+
+ if (type != None)
+ XFree (prop.prop);
+}
+
+static void
+gtk_tray_icon_get_icon_size_property (GtkTrayIcon *icon)
+{
+ GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (icon));
+ GdkDisplay *display = gdk_screen_get_display (screen);
+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ Atom type;
+ int format;
+ union {
+ gulong *prop;
+ guchar *prop_ch;
+ } prop = { NULL };
+ gulong nitems;
+ gulong bytes_after;
+ int error, result;
+
+ g_assert (icon->priv->manager_window != None);
+
+ gdk_error_trap_push ();
+ type = None;
+ result = XGetWindowProperty (xdisplay,
+ icon->priv->manager_window,
+ icon->priv->icon_size_atom,
+ 0, G_MAXLONG, FALSE,
+ XA_CARDINAL,
+ &type, &format, &nitems,
+ &bytes_after, &(prop.prop_ch));
+ error = gdk_error_trap_pop ();
+
+ if (!error && result == Success &&
+ type == XA_CARDINAL && nitems == 1 && format == 32)
+ {
+ gint icon_size;
+
+ icon_size = prop.prop[0];
+
+ if (icon->priv->icon_size != icon_size)
+ {
+ icon->priv->icon_size = icon_size;
+
+ g_object_notify (G_OBJECT (icon), "icon-size");
+ }
+ }
+
+ if (type != None)
+ XFree (prop.prop);
+}
+
+static GdkFilterReturn
+gtk_tray_icon_manager_filter (GdkXEvent *xevent,
+ GdkEvent *event,
+ gpointer user_data)
+{
+ GtkTrayIcon *icon = user_data;
+ XEvent *xev = (XEvent *)xevent;
+
+ if (xev->xany.type == ClientMessage &&
+ xev->xclient.message_type == icon->priv->manager_atom &&
+ xev->xclient.data.l[1] == icon->priv->selection_atom)
+ {
+ GTK_NOTE (PLUGSOCKET,
+ g_print ("GtkStatusIcon %p: tray manager appeared\n", icon));
+
+ gtk_tray_icon_update_manager_window (icon);
+ }
+ else if (xev->xany.window == icon->priv->manager_window)
+ {
+ if (xev->xany.type == PropertyNotify &&
+ xev->xproperty.atom == icon->priv->orientation_atom)
+ {
+ GTK_NOTE (PLUGSOCKET,
+ g_print ("GtkStatusIcon %p: got PropertyNotify on manager window for orientation atom\n", icon));
+
+ gtk_tray_icon_get_orientation_property (icon);
+ }
+ else if (xev->xany.type == PropertyNotify &&
+ xev->xproperty.atom == icon->priv->colors_atom)
+ {
+ GTK_NOTE (PLUGSOCKET,
+ g_print ("GtkStatusIcon %p: got PropertyNotify on manager window for colors atom\n", icon));
+
+ gtk_tray_icon_get_colors_property (icon);
+ }
+ else if (xev->xany.type == PropertyNotify &&
+ xev->xproperty.atom == icon->priv->padding_atom)
+ {
+ gtk_tray_icon_get_padding_property (icon);
+ }
+ else if (xev->xany.type == PropertyNotify &&
+ xev->xproperty.atom == icon->priv->icon_size_atom)
+ {
+ gtk_tray_icon_get_icon_size_property (icon);
+ }
+ else if (xev->xany.type == DestroyNotify)
+ {
+ GTK_NOTE (PLUGSOCKET,
+ g_print ("GtkStatusIcon %p: got DestroyNotify for manager window\n", icon));
+
+ gtk_tray_icon_manager_window_destroyed (icon);
+ }
+ else
+ {
+ GTK_NOTE (PLUGSOCKET,
+ g_print ("GtkStatusIcon %p: got other message on manager window\n", icon));
+ }
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+static void
+gtk_tray_icon_send_manager_message (GtkTrayIcon *icon,
+ long message,
+ Window window,
+ long data1,
+ long data2,
+ long data3)
+{
+ GtkWidget *widget;
+ XClientMessageEvent ev;
+ Display *display;
+
+ widget = GTK_WIDGET (icon);
+
+ memset (&ev, 0, sizeof (ev));
+ ev.type = ClientMessage;
+ ev.window = window;
+ ev.message_type = icon->priv->system_tray_opcode_atom;
+ ev.format = 32;
+ ev.data.l[0] = gdk_x11_get_server_time (gtk_widget_get_window (widget));
+ ev.data.l[1] = message;
+ ev.data.l[2] = data1;
+ ev.data.l[3] = data2;
+ ev.data.l[4] = data3;
+
+ display = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget));
+
+ gdk_error_trap_push ();
+ XSendEvent (display,
+ icon->priv->manager_window, False, NoEventMask, (XEvent *)&ev);
+ gdk_error_trap_pop_ignored ();
+}
+
+static void
+gtk_tray_icon_send_dock_request (GtkTrayIcon *icon)
+{
+ GTK_NOTE (PLUGSOCKET,
+ g_print ("GtkStatusIcon %p: sending dock request to manager window %lx\n",
+ icon, (gulong) icon->priv->manager_window));
+
+ gtk_tray_icon_send_manager_message (icon,
+ SYSTEM_TRAY_REQUEST_DOCK,
+ icon->priv->manager_window,
+ gtk_plug_get_id (GTK_PLUG (icon)),
+ 0, 0);
+}
+
+static void
+gtk_tray_icon_update_manager_window (GtkTrayIcon *icon)
+{
+ GtkWidget *widget = GTK_WIDGET (icon);
+ GdkScreen *screen = gtk_widget_get_screen (widget);
+ GdkDisplay *display = gdk_screen_get_display (screen);
+ Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
+
+ GTK_NOTE (PLUGSOCKET,
+ g_print ("GtkStatusIcon %p: updating tray icon manager window, current manager window: %lx\n",
+ icon, (gulong) icon->priv->manager_window));
+
+ if (icon->priv->manager_window != None)
+ return;
+
+ GTK_NOTE (PLUGSOCKET,
+ g_print ("GtkStatusIcon %p: trying to find manager window\n", icon));
+
+ XGrabServer (xdisplay);
+
+ icon->priv->manager_window = XGetSelectionOwner (xdisplay,
+ icon->priv->selection_atom);
+
+ if (icon->priv->manager_window != None)
+ XSelectInput (xdisplay,
+ icon->priv->manager_window, StructureNotifyMask|PropertyChangeMask);
+
+ XUngrabServer (xdisplay);
+ XFlush (xdisplay);
+
+ if (icon->priv->manager_window != None)
+ {
+ GdkWindow *gdkwin;
+
+ GTK_NOTE (PLUGSOCKET,
+ g_print ("GtkStatusIcon %p: is being managed by window %lx\n",
+ icon, (gulong) icon->priv->manager_window));
+
+ gdkwin = gdk_x11_window_lookup_for_display (display,
+ icon->priv->manager_window);
+
+ gdk_window_add_filter (gdkwin, gtk_tray_icon_manager_filter, icon);
+
+ gtk_tray_icon_get_orientation_property (icon);
+ gtk_tray_icon_get_visual_property (icon);
+ gtk_tray_icon_get_colors_property (icon);
+ gtk_tray_icon_get_padding_property (icon);
+ gtk_tray_icon_get_icon_size_property (icon);
+
+ if (gtk_widget_get_realized (GTK_WIDGET (icon)))
+ {
+ if ((icon->priv->manager_visual == NULL &&
+ gtk_widget_get_visual (widget) == gdk_screen_get_system_visual (screen)) ||
+ (icon->priv->manager_visual == gtk_widget_get_visual (widget)))
+ {
+ /* Already have the right visual, can just dock
+ */
+ gtk_tray_icon_send_dock_request (icon);
+ }
+ else
+ {
+ /* Need to re-realize the widget to get the right visual
+ */
+ gtk_widget_hide (widget);
+ gtk_widget_unrealize (widget);
+ gtk_widget_show (widget);
+ }
+ }
+ }
+ else
+ {
+ GTK_NOTE (PLUGSOCKET,
+ g_print ("GtkStatusIcon %p: no tray manager found\n", icon));
+ }
+}
+
+static void
+gtk_tray_icon_manager_window_destroyed (GtkTrayIcon *icon)
+{
+ g_return_if_fail (icon->priv->manager_window != None);
+
+ GTK_NOTE (PLUGSOCKET,
+ g_print ("GtkStatusIcon %p: tray manager window destroyed\n", icon));
+
+ gtk_tray_icon_clear_manager_window (icon);
+}
+
+static gboolean
+gtk_tray_icon_delete (GtkWidget *widget,
+ GdkEventAny *event)
+{
+#ifdef G_ENABLE_DEBUG
+ GtkTrayIcon *icon = GTK_TRAY_ICON (widget);
+#endif
+
+ GTK_NOTE (PLUGSOCKET,
+ g_print ("GtkStatusIcon %p: delete notify, tray manager window %lx\n",
+ icon, (gulong) icon->priv->manager_window));
+
+ /* A bug in X server versions up to x.org 1.5.0 means that:
+ * XFixesChangeSaveSet(...., SaveSetRoot, SaveSetUnmap) doesn't work properly
+ * and we'll left mapped in a separate toplevel window if the tray is destroyed.
+ * For simplicity just get rid of our X window and start over.
+ */
+ gtk_widget_hide (widget);
+ gtk_widget_unrealize (widget);
+ gtk_widget_show (widget);
+
+ /* Handled it, don't destroy the tray icon */
+ return TRUE;
+}
+
+static void
+gtk_tray_icon_set_visual (GtkTrayIcon *icon)
+{
+ GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (icon));
+ GdkVisual *visual = icon->priv->manager_visual;
+
+ /* To avoid uncertainty about colormaps, _NET_SYSTEM_TRAY_VISUAL is supposed
+ * to be either the screen default visual or a TrueColor visual; ignore it
+ * if it is something else
+ */
+ if (visual && gdk_visual_get_visual_type (visual) != GDK_VISUAL_TRUE_COLOR)
+ visual = NULL;
+
+ if (visual == NULL)
+ visual = gdk_screen_get_system_visual (screen);
+
+ gtk_widget_set_visual (GTK_WIDGET (icon), visual);
+}
+
+static void
+gtk_tray_icon_realize (GtkWidget *widget)
+{
+ GtkTrayIcon *icon = GTK_TRAY_ICON (widget);
+ GdkWindow *window;
+
+ /* Set our visual before realizing */
+ gtk_tray_icon_set_visual (icon);
+
+ GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->realize (widget);
+ window = gtk_widget_get_window (widget);
+ if (icon->priv->manager_visual_rgba)
+ {
+ /* Set a transparent background */
+ GdkRGBA transparent = { 0.0, 0.0, 0.0, 0.0 };
+ gdk_window_set_background_rgba (window, &transparent);
+ }
+ else
+ {
+ /* Set a parent-relative background pixmap */
+ gdk_window_set_background_pattern (window, NULL);
+ }
+
+ GTK_NOTE (PLUGSOCKET,
+ g_print ("GtkStatusIcon %p: realized, window: %lx, socket window: %lx\n",
+ widget,
+ (gulong) GDK_WINDOW_XID (window),
+ gtk_plug_get_socket_window (GTK_PLUG (icon)) ?
+ (gulong) GDK_WINDOW_XID (gtk_plug_get_socket_window (GTK_PLUG (icon))) : 0UL));
+
+ if (icon->priv->manager_window != None)
+ gtk_tray_icon_send_dock_request (icon);
+}
+
+static void
+gtk_tray_icon_style_updated (GtkWidget *widget)
+{
+ /* The default handler resets the background according to the style. We either
+ * use a transparent background or a parent-relative background and ignore the
+ * style background. So, just don't chain up.
+ */
+}
+
+guint
+_gtk_tray_icon_send_message (GtkTrayIcon *icon,
+ gint timeout,
+ const gchar *message,
+ gint len)
+{
+ guint stamp;
+ Display *xdisplay;
+
+ g_return_val_if_fail (GTK_IS_TRAY_ICON (icon), 0);
+ g_return_val_if_fail (timeout >= 0, 0);
+ g_return_val_if_fail (message != NULL, 0);
+
+ if (icon->priv->manager_window == None)
+ return 0;
+
+ if (len < 0)
+ len = strlen (message);
+
+ stamp = icon->priv->stamp++;
+
+ /* Get ready to send the message */
+ gtk_tray_icon_send_manager_message (icon, SYSTEM_TRAY_BEGIN_MESSAGE,
+ (Window)gtk_plug_get_id (GTK_PLUG (icon)),
+ timeout, len, stamp);
+
+ /* Now to send the actual message */
+ xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
+ gdk_error_trap_push ();
+ while (len > 0)
+ {
+ XClientMessageEvent ev;
+
+ memset (&ev, 0, sizeof (ev));
+ ev.type = ClientMessage;
+ ev.window = (Window)gtk_plug_get_id (GTK_PLUG (icon));
+ ev.format = 8;
+ ev.message_type = XInternAtom (xdisplay,
+ "_NET_SYSTEM_TRAY_MESSAGE_DATA", False);
+ if (len > 20)
+ {
+ memcpy (&ev.data, message, 20);
+ len -= 20;
+ message += 20;
+ }
+ else
+ {
+ memcpy (&ev.data, message, len);
+ len = 0;
+ }
+
+ XSendEvent (xdisplay,
+ icon->priv->manager_window, False,
+ StructureNotifyMask, (XEvent *)&ev);
+ }
+ gdk_error_trap_pop_ignored ();
+
+ return stamp;
+}
+
+void
+_gtk_tray_icon_cancel_message (GtkTrayIcon *icon,
+ guint id)
+{
+ g_return_if_fail (GTK_IS_TRAY_ICON (icon));
+ g_return_if_fail (id > 0);
+
+ gtk_tray_icon_send_manager_message (icon, SYSTEM_TRAY_CANCEL_MESSAGE,
+ (Window)gtk_plug_get_id (GTK_PLUG (icon)),
+ id, 0, 0);
+}
+
+GtkTrayIcon *
+_gtk_tray_icon_new_for_screen (GdkScreen *screen,
+ const gchar *name)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ return g_object_new (GTK_TYPE_TRAY_ICON,
+ "screen", screen,
+ "title", name,
+ NULL);
+}
+
+GtkTrayIcon*
+_gtk_tray_icon_new (const gchar *name)
+{
+ return g_object_new (GTK_TYPE_TRAY_ICON,
+ "title", name,
+ NULL);
+}
+
+GtkOrientation
+_gtk_tray_icon_get_orientation (GtkTrayIcon *icon)
+{
+ g_return_val_if_fail (GTK_IS_TRAY_ICON (icon), GTK_ORIENTATION_HORIZONTAL);
+
+ return icon->priv->orientation;
+}
+
+gint
+_gtk_tray_icon_get_padding (GtkTrayIcon *icon)
+{
+ g_return_val_if_fail (GTK_IS_TRAY_ICON (icon), 0);
+
+ return icon->priv->padding;
+}
+
+gint
+_gtk_tray_icon_get_icon_size (GtkTrayIcon *icon)
+{
+ g_return_val_if_fail (GTK_IS_TRAY_ICON (icon), 0);
+
+ return icon->priv->icon_size;
+}
--- /dev/null
+/* gtktrayicon.h
+ * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GTK_TRAY_ICON_H__
+#define __GTK_TRAY_ICON_H__
+
+#include "gtkplug.h"
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_TRAY_ICON (gtk_tray_icon_get_type ())
+#define GTK_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TRAY_ICON, GtkTrayIcon))
+#define GTK_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TRAY_ICON, GtkTrayIconClass))
+#define GTK_IS_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TRAY_ICON))
+#define GTK_IS_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TRAY_ICON))
+#define GTK_TRAY_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TRAY_ICON, GtkTrayIconClass))
+
+typedef struct _GtkTrayIcon GtkTrayIcon;
+typedef struct _GtkTrayIconPrivate GtkTrayIconPrivate;
+typedef struct _GtkTrayIconClass GtkTrayIconClass;
+
+struct _GtkTrayIcon
+{
+ GtkPlug parent_instance;
+
+ GtkTrayIconPrivate *priv;
+};
+
+struct _GtkTrayIconClass
+{
+ GtkPlugClass parent_class;
+
+ /* Padding for future expansion */
+ void (*_gtk_reserved1);
+ void (*_gtk_reserved2);
+ void (*_gtk_reserved3);
+ void (*_gtk_reserved4);
+};
+
+GDK_AVAILABLE_IN_ALL
+GType gtk_tray_icon_get_type (void) G_GNUC_CONST;
+
+GtkTrayIcon *_gtk_tray_icon_new_for_screen (GdkScreen *screen,
+ const gchar *name);
+
+GtkTrayIcon *_gtk_tray_icon_new (const gchar *name);
+
+guint _gtk_tray_icon_send_message (GtkTrayIcon *icon,
+ gint timeout,
+ const gchar *message,
+ gint len);
+void _gtk_tray_icon_cancel_message (GtkTrayIcon *icon,
+ guint id);
+
+GtkOrientation _gtk_tray_icon_get_orientation (GtkTrayIcon *icon);
+gint _gtk_tray_icon_get_padding (GtkTrayIcon *icon);
+gint _gtk_tray_icon_get_icon_size (GtkTrayIcon *icon);
+
+G_END_DECLS
+
+#endif /* __GTK_TRAY_ICON_H__ */
#include <gtk/gtkstack.h>
#include <gtk/gtkstackswitcher.h>
#include <gtk/gtkstatusbar.h>
-#include <gtk/gtkstatusicon.h>
#include <gtk/gtkstylecontext.h>
#include <gtk/gtkstyleproperties.h>
#include <gtk/gtkstyleprovider.h>
#include <gtk/deprecated/gtkradioaction.h>
#include <gtk/deprecated/gtkrc.h>
#include <gtk/deprecated/gtkrecentaction.h>
+#include <gtk/deprecated/gtkstatusicon.h>
#include <gtk/deprecated/gtkstock.h>
#include <gtk/deprecated/gtkstyle.h>
#include <gtk/deprecated/gtksymboliccolor.h>
+++ /dev/null
-/* gtkstatusicon-quartz.c:
- *
- * Copyright (C) 2006 Imendio AB
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * GCC on Mac OS X handles inlined objective C in C-files.
- *
- * Authors:
- * Mikael Hallendal <micke@imendio.com>
- */
-
-#import <Cocoa/Cocoa.h>
-#include <quartz/gdkquartz.h>
-
-#define QUARTZ_POOL_ALLOC NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]
-#define QUARTZ_POOL_RELEASE [pool release]
-
-@interface GtkQuartzStatusIcon : NSObject
-{
- GtkStatusIcon *status_icon;
- NSStatusBar *ns_bar;
- NSStatusItem *ns_item;
- NSImage *current_image;
- NSString *ns_tooltip;
-}
-- (id) initWithStatusIcon:(GtkStatusIcon *)status_icon;
-- (void) ensureItem;
-- (void) actionCb:(NSObject *)button;
-- (void) setImage:(GdkPixbuf *)pixbuf;
-- (void) setVisible:(gboolean)visible;
-- (void) setToolTip:(const gchar *)tooltip_text;
-- (float) getWidth;
-- (float) getHeight;
-@end
-
-@implementation GtkQuartzStatusIcon : NSObject
-- (id) initWithStatusIcon:(GtkStatusIcon *)icon
-{
- [super init];
- status_icon = icon;
- ns_bar = [NSStatusBar systemStatusBar];
-
- return self;
-}
-
-- (void) ensureItem
-{
- if (ns_item != nil)
- return;
-
- ns_item = [ns_bar statusItemWithLength:NSVariableStatusItemLength];
- [ns_item setAction:@selector(actionCb:)];
- [ns_item setTarget:self];
- [ns_item retain];
-}
-
-- (void) dealloc
-{
- g_print ("Deallocating GtkQuartzStatusIcon\n");
- [current_image release];
- [ns_item release];
- [ns_bar release];
-
- [super dealloc];
-}
-
-- (void) actionCb:(NSObject *)button
-{
- NSEvent *event = [NSApp currentEvent];
- double time = [event timestamp];
-
- g_signal_emit (status_icon,
- status_icon_signals [POPUP_MENU_SIGNAL], 0,
- 1,
- time * 1000.0);
-}
-
-- (void) setImage:(GdkPixbuf *)pixbuf
-{
- /* Support NULL */
- [self ensureItem];
-
- if (current_image != nil) {
- [current_image release];
- current_image = nil;
- }
-
- if (!pixbuf) {
- [ns_item release];
- ns_item = nil;
- return;
- }
-
- current_image = gdk_quartz_pixbuf_to_ns_image_libgtk_only (pixbuf);
- [current_image retain];
-
- [ns_item setImage:current_image];
-}
-
-- (void) setVisible:(gboolean)visible
-{
- if (visible) {
- [self ensureItem];
- if (ns_item != nil)
- [ns_item setImage:current_image];
- if (ns_tooltip != nil)
- [ns_item setToolTip:ns_tooltip];
- } else {
- [ns_item release];
- ns_item = nil;
- }
-}
-
-- (void) setToolTip:(const gchar *)tooltip_text
-{
- [ns_tooltip release];
- ns_tooltip = [[NSString stringWithUTF8String:tooltip_text] retain];
-
- [ns_item setToolTip:ns_tooltip];
-}
-
-- (float) getWidth
-{
- return [ns_bar thickness];
-}
-
-- (float) getHeight
-{
- return [ns_bar thickness];
-}
-@end
-
-
-
+++ /dev/null
-/* gtkstatusicon.c:
- *
- * Copyright (C) 2003 Sun Microsystems, Inc.
- * Copyright (C) 2005 Hans Breuer <hans@breuer.org>
- * Copyright (C) 2005 Novell, Inc.
- * Copyright (C) 2006 Imendio AB
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Mark McLoughlin <mark@skynet.ie>
- * Hans Breuer <hans@breuer.org>
- * Tor Lillqvist <tml@novell.com>
- * Mikael Hallendal <micke@imendio.com>
- */
-
-#include "config.h"
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "gtkstatusicon.h"
-
-#include "gtkintl.h"
-#include "gtkiconhelperprivate.h"
-#include "gtkmain.h"
-#include "gtkmarshalers.h"
-#include "gtksizerequest.h"
-#include "gtkprivate.h"
-#include "gtkwidget.h"
-#include "gtktooltip.h"
-#include "gtkicontheme.h"
-#include "gtklabel.h"
-#include "gtktypebuiltins.h"
-
-#ifdef GDK_WINDOWING_X11
-#include "gdk/x11/gdkx.h"
-#include "gtktrayicon.h"
-#endif
-
-#ifdef GDK_WINDOWING_WIN32
-#include "gdk/win32/gdkwin32.h"
-#define WM_GTK_TRAY_NOTIFICATION (WM_USER+1)
-#endif
-
-
-/**
- * SECTION:gtkstatusicon
- * @Short_description: Display an icon in the system tray
- * @Title: GtkStatusIcon
- *
- * The “system tray” or notification area is normally used for transient icons
- * that indicate some special state. For example, a system tray icon might
- * appear to tell the user that they have new mail, or have an incoming instant
- * message, or something along those lines. The basic idea is that creating an
- * icon in the notification area is less annoying than popping up a dialog.
- *
- * A #GtkStatusIcon object can be used to display an icon in a “system tray”.
- * The icon can have a tooltip, and the user can interact with it by
- * activating it or popping up a context menu. Critical information should
- * not solely be displayed in a #GtkStatusIcon, since it may not be
- * visible (e.g. when the user doesn’t have a notification area on his panel).
- * This can be checked with gtk_status_icon_is_embedded().
- *
- * On X11, the implementation follows the
- * [FreeDesktop System Tray Specification](http://www.freedesktop.org/wiki/Specifications/systemtray-spec).
- * Implementations of the “tray” side of this specification can
- * be found e.g. in the GNOME 2 and KDE panel applications.
- *
- * Note that a GtkStatusIcon is not a widget, but just
- * a #GObject. Making it a widget would be impractical, since the system tray
- * on Win32 doesn’t allow to embed arbitrary widgets.
- */
-
-
-#define BLINK_TIMEOUT 500
-
-enum
-{
- PROP_0,
- PROP_PIXBUF,
- PROP_FILE,
- PROP_STOCK,
- PROP_ICON_NAME,
- PROP_GICON,
- PROP_STORAGE_TYPE,
- PROP_SIZE,
- PROP_SCREEN,
- PROP_VISIBLE,
- PROP_ORIENTATION,
- PROP_EMBEDDED,
- PROP_BLINKING,
- PROP_HAS_TOOLTIP,
- PROP_TOOLTIP_TEXT,
- PROP_TOOLTIP_MARKUP,
- PROP_TITLE
-};
-
-enum
-{
- ACTIVATE_SIGNAL,
- POPUP_MENU_SIGNAL,
- SIZE_CHANGED_SIGNAL,
- BUTTON_PRESS_EVENT_SIGNAL,
- BUTTON_RELEASE_EVENT_SIGNAL,
- SCROLL_EVENT_SIGNAL,
- QUERY_TOOLTIP_SIGNAL,
- LAST_SIGNAL
-};
-
-static guint status_icon_signals [LAST_SIGNAL] = { 0 };
-
-#ifdef GDK_WINDOWING_QUARTZ
-#include "gtkstatusicon-quartz.c"
-#endif
-
-struct _GtkStatusIconPrivate
-{
-#ifdef GDK_WINDOWING_X11
- GtkWidget *tray_icon;
- GtkWidget *image;
-#else
- GtkWidget *dummy_widget;
-#endif
-
-#ifdef GDK_WINDOWING_WIN32
- NOTIFYICONDATAW nid;
- gint taskbar_top;
- gint last_click_x, last_click_y;
- GtkOrientation orientation;
- gchar *tooltip_text;
- gchar *title;
-#endif
-
-#ifdef GDK_WINDOWING_QUARTZ
- GtkQuartzStatusIcon *status_item;
- gchar *tooltip_text;
- gchar *title;
-#endif
-
- gint size;
- GtkIconHelper *icon_helper;
- guint visible : 1;
-};
-
-static void gtk_status_icon_constructed (GObject *object);
-static void gtk_status_icon_finalize (GObject *object);
-static void gtk_status_icon_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gtk_status_icon_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-
-#ifdef GDK_WINDOWING_X11
-static void gtk_status_icon_size_allocate (GtkStatusIcon *status_icon,
- GtkAllocation *allocation);
-static void gtk_status_icon_screen_changed (GtkStatusIcon *status_icon,
- GdkScreen *old_screen);
-static void gtk_status_icon_embedded_changed (GtkStatusIcon *status_icon);
-static void gtk_status_icon_orientation_changed (GtkStatusIcon *status_icon);
-static void gtk_status_icon_padding_changed (GtkStatusIcon *status_icon);
-static void gtk_status_icon_icon_size_changed(GtkStatusIcon *status_icon);
-static void gtk_status_icon_fg_changed (GtkStatusIcon *status_icon);
-static void gtk_status_icon_color_changed (GtkTrayIcon *tray,
- GParamSpec *pspec,
- GtkStatusIcon *status_icon);
-static gboolean gtk_status_icon_scroll (GtkStatusIcon *status_icon,
- GdkEventScroll *event);
-static gboolean gtk_status_icon_query_tooltip (GtkStatusIcon *status_icon,
- gint x,
- gint y,
- gboolean keyboard_tip,
- GtkTooltip *tooltip);
-
-static gboolean gtk_status_icon_key_press (GtkStatusIcon *status_icon,
- GdkEventKey *event);
-static void gtk_status_icon_popup_menu (GtkStatusIcon *status_icon);
-#endif
-static gboolean gtk_status_icon_button_press (GtkStatusIcon *status_icon,
- GdkEventButton *event);
-static gboolean gtk_status_icon_button_release (GtkStatusIcon *status_icon,
- GdkEventButton *event);
-static void gtk_status_icon_reset_image_data (GtkStatusIcon *status_icon);
-static void gtk_status_icon_update_image (GtkStatusIcon *status_icon);
-
-G_DEFINE_TYPE_WITH_PRIVATE (GtkStatusIcon, gtk_status_icon, G_TYPE_OBJECT)
-
-static void
-gtk_status_icon_class_init (GtkStatusIconClass *class)
-{
- GObjectClass *gobject_class = (GObjectClass *) class;
-
- gobject_class->constructed = gtk_status_icon_constructed;
- gobject_class->finalize = gtk_status_icon_finalize;
- gobject_class->set_property = gtk_status_icon_set_property;
- gobject_class->get_property = gtk_status_icon_get_property;
-
- class->button_press_event = NULL;
- class->button_release_event = NULL;
- class->scroll_event = NULL;
- class->query_tooltip = NULL;
-
- g_object_class_install_property (gobject_class,
- PROP_PIXBUF,
- g_param_spec_object ("pixbuf",
- P_("Pixbuf"),
- P_("A GdkPixbuf to display"),
- GDK_TYPE_PIXBUF,
- GTK_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class,
- PROP_FILE,
- g_param_spec_string ("file",
- P_("Filename"),
- P_("Filename to load and display"),
- NULL,
- GTK_PARAM_WRITABLE));
-
- /**
- * GtkStatusIcon:stock:
- *
- * Deprecated: 3.10: Use #GtkStatusIcon:icon-name instead.
- */
- g_object_class_install_property (gobject_class,
- PROP_STOCK,
- g_param_spec_string ("stock",
- P_("Stock ID"),
- P_("Stock ID for a stock image to display"),
- NULL,
- GTK_PARAM_READWRITE | G_PARAM_DEPRECATED));
-
- g_object_class_install_property (gobject_class,
- PROP_ICON_NAME,
- g_param_spec_string ("icon-name",
- P_("Icon Name"),
- P_("The name of the icon from the icon theme"),
- NULL,
- GTK_PARAM_READWRITE));
-
- /**
- * GtkStatusIcon:gicon:
- *
- * The #GIcon displayed in the #GtkStatusIcon. For themed icons,
- * the image will be updated automatically if the theme changes.
- *
- * Since: 2.14
- */
- g_object_class_install_property (gobject_class,
- PROP_GICON,
- g_param_spec_object ("gicon",
- P_("GIcon"),
- P_("The GIcon being displayed"),
- G_TYPE_ICON,
- GTK_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class,
- PROP_STORAGE_TYPE,
- g_param_spec_enum ("storage-type",
- P_("Storage type"),
- P_("The representation being used for image data"),
- GTK_TYPE_IMAGE_TYPE,
- GTK_IMAGE_EMPTY,
- GTK_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_SIZE,
- g_param_spec_int ("size",
- P_("Size"),
- P_("The size of the icon"),
- 0,
- G_MAXINT,
- 0,
- GTK_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_SCREEN,
- g_param_spec_object ("screen",
- P_("Screen"),
- P_("The screen where this status icon will be displayed"),
- GDK_TYPE_SCREEN,
- GTK_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class,
- PROP_VISIBLE,
- g_param_spec_boolean ("visible",
- P_("Visible"),
- P_("Whether the status icon is visible"),
- TRUE,
- GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
-
-
- /**
- * GtkStatusIcon:embedded:
- *
- * %TRUE if the statusicon is embedded in a notification area.
- *
- * Since: 2.12
- */
- g_object_class_install_property (gobject_class,
- PROP_EMBEDDED,
- g_param_spec_boolean ("embedded",
- P_("Embedded"),
- P_("Whether the status icon is embedded"),
- FALSE,
- GTK_PARAM_READABLE));
-
- /**
- * GtkStatusIcon:orientation:
- *
- * The orientation of the tray in which the statusicon
- * is embedded.
- *
- * Since: 2.12
- */
- g_object_class_install_property (gobject_class,
- PROP_ORIENTATION,
- g_param_spec_enum ("orientation",
- P_("Orientation"),
- P_("The orientation of the tray"),
- GTK_TYPE_ORIENTATION,
- GTK_ORIENTATION_HORIZONTAL,
- GTK_PARAM_READABLE));
-
-/**
- * GtkStatusIcon:has-tooltip:
- *
- * Enables or disables the emission of #GtkStatusIcon::query-tooltip on
- * @status_icon. A value of %TRUE indicates that @status_icon can have a
- * tooltip, in this case the status icon will be queried using
- * #GtkStatusIcon::query-tooltip to determine whether it will provide a
- * tooltip or not.
- *
- * Note that setting this property to %TRUE for the first time will change
- * the event masks of the windows of this status icon to include leave-notify
- * and motion-notify events. This will not be undone when the property is set
- * to %FALSE again.
- *
- * Whether this property is respected is platform dependent.
- * For plain text tooltips, use #GtkStatusIcon:tooltip-text in preference.
- *
- * Since: 2.16
- */
- g_object_class_install_property (gobject_class,
- PROP_HAS_TOOLTIP,
- g_param_spec_boolean ("has-tooltip",
- P_("Has tooltip"),
- P_("Whether this tray icon has a tooltip"),
- FALSE,
- GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
-
- /**
- * GtkStatusIcon:tooltip-text:
- *
- * Sets the text of tooltip to be the given string.
- *
- * Also see gtk_tooltip_set_text().
- *
- * This is a convenience property which will take care of getting the
- * tooltip shown if the given string is not %NULL.
- * #GtkStatusIcon:has-tooltip will automatically be set to %TRUE and
- * the default handler for the #GtkStatusIcon::query-tooltip signal
- * will take care of displaying the tooltip.
- *
- * Note that some platforms have limitations on the length of tooltips
- * that they allow on status icons, e.g. Windows only shows the first
- * 64 characters.
- *
- * Since: 2.16
- */
- g_object_class_install_property (gobject_class,
- PROP_TOOLTIP_TEXT,
- g_param_spec_string ("tooltip-text",
- P_("Tooltip Text"),
- P_("The contents of the tooltip for this widget"),
- NULL,
- GTK_PARAM_READWRITE));
- /**
- * GtkStatusIcon:tooltip-markup:
- *
- * Sets the text of tooltip to be the given string, which is marked up
- * with the [Pango text markup language][PangoMarkupFormat].
- * Also see gtk_tooltip_set_markup().
- *
- * This is a convenience property which will take care of getting the
- * tooltip shown if the given string is not %NULL.
- * #GtkStatusIcon:has-tooltip will automatically be set to %TRUE and
- * the default handler for the #GtkStatusIcon::query-tooltip signal
- * will take care of displaying the tooltip.
- *
- * On some platforms, embedded markup will be ignored.
- *
- * Since: 2.16
- */
- g_object_class_install_property (gobject_class,
- PROP_TOOLTIP_MARKUP,
- g_param_spec_string ("tooltip-markup",
- P_("Tooltip markup"),
- P_("The contents of the tooltip for this tray icon"),
- NULL,
- GTK_PARAM_READWRITE));
-
-
- /**
- * GtkStatusIcon:title:
- *
- * The title of this tray icon. This should be a short, human-readable,
- * localized string describing the tray icon. It may be used by tools
- * like screen readers to render the tray icon.
- *
- * Since: 2.18
- */
- g_object_class_install_property (gobject_class,
- PROP_TITLE,
- g_param_spec_string ("title",
- P_("Title"),
- P_("The title of this tray icon"),
- NULL,
- GTK_PARAM_READWRITE));
-
- /**
- * GtkStatusIcon::activate:
- * @status_icon: the object which received the signal
- *
- * Gets emitted when the user activates the status icon.
- * If and how status icons can activated is platform-dependent.
- *
- * Unlike most G_SIGNAL_ACTION signals, this signal is meant to
- * be used by applications and should be wrapped by language bindings.
- *
- * Since: 2.10
- */
- status_icon_signals [ACTIVATE_SIGNAL] =
- g_signal_new (I_("activate"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET (GtkStatusIconClass, activate),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- /**
- * GtkStatusIcon::popup-menu:
- * @status_icon: the object which received the signal
- * @button: the button that was pressed, or 0 if the
- * signal is not emitted in response to a button press event
- * @activate_time: the timestamp of the event that
- * triggered the signal emission
- *
- * Gets emitted when the user brings up the context menu
- * of the status icon. Whether status icons can have context
- * menus and how these are activated is platform-dependent.
- *
- * The @button and @activate_time parameters should be
- * passed as the last to arguments to gtk_menu_popup().
- *
- * Unlike most G_SIGNAL_ACTION signals, this signal is meant to
- * be used by applications and should be wrapped by language bindings.
- *
- * Since: 2.10
- */
- status_icon_signals [POPUP_MENU_SIGNAL] =
- g_signal_new (I_("popup-menu"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET (GtkStatusIconClass, popup_menu),
- NULL,
- NULL,
- _gtk_marshal_VOID__UINT_UINT,
- G_TYPE_NONE,
- 2,
- G_TYPE_UINT,
- G_TYPE_UINT);
-
- /**
- * GtkStatusIcon::size-changed:
- * @status_icon: the object which received the signal
- * @size: the new size
- *
- * Gets emitted when the size available for the image
- * changes, e.g. because the notification area got resized.
- *
- * Returns: %TRUE if the icon was updated for the new
- * size. Otherwise, GTK+ will scale the icon as necessary.
- *
- * Since: 2.10
- */
- status_icon_signals [SIZE_CHANGED_SIGNAL] =
- g_signal_new (I_("size-changed"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GtkStatusIconClass, size_changed),
- g_signal_accumulator_true_handled,
- NULL,
- _gtk_marshal_BOOLEAN__INT,
- G_TYPE_BOOLEAN,
- 1,
- G_TYPE_INT);
-
- /**
- * GtkStatusIcon::button-press-event:
- * @status_icon: the object which received the signal
- * @event: (type Gdk.EventButton): the #GdkEventButton which triggered
- * this signal
- *
- * The ::button-press-event signal will be emitted when a button
- * (typically from a mouse) is pressed.
- *
- * Whether this event is emitted is platform-dependent. Use the ::activate
- * and ::popup-menu signals in preference.
- *
- * Returns: %TRUE to stop other handlers from being invoked
- * for the event. %FALSE to propagate the event further.
- *
- * Since: 2.14
- */
- status_icon_signals [BUTTON_PRESS_EVENT_SIGNAL] =
- g_signal_new (I_("button_press_event"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GtkStatusIconClass, button_press_event),
- g_signal_accumulator_true_handled, NULL,
- _gtk_marshal_BOOLEAN__BOXED,
- G_TYPE_BOOLEAN, 1,
- GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
- /**
- * GtkStatusIcon::button-release-event:
- * @status_icon: the object which received the signal
- * @event: (type Gdk.EventButton): the #GdkEventButton which triggered
- * this signal
- *
- * The ::button-release-event signal will be emitted when a button
- * (typically from a mouse) is released.
- *
- * Whether this event is emitted is platform-dependent. Use the ::activate
- * and ::popup-menu signals in preference.
- *
- * Returns: %TRUE to stop other handlers from being invoked
- * for the event. %FALSE to propagate the event further.
- *
- * Since: 2.14
- */
- status_icon_signals [BUTTON_RELEASE_EVENT_SIGNAL] =
- g_signal_new (I_("button_release_event"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GtkStatusIconClass, button_release_event),
- g_signal_accumulator_true_handled, NULL,
- _gtk_marshal_BOOLEAN__BOXED,
- G_TYPE_BOOLEAN, 1,
- GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
- /**
- * GtkStatusIcon::scroll-event:
- * @status_icon: the object which received the signal.
- * @event: (type Gdk.EventScroll): the #GdkEventScroll which triggered
- * this signal
- *
- * The ::scroll-event signal is emitted when a button in the 4 to 7
- * range is pressed. Wheel mice are usually configured to generate
- * button press events for buttons 4 and 5 when the wheel is turned.
- *
- * Whether this event is emitted is platform-dependent.
- *
- * Returns: %TRUE to stop other handlers from being invoked for the event.
- * %FALSE to propagate the event further.
- *
- * Since: 2.16
- */
- status_icon_signals[SCROLL_EVENT_SIGNAL] =
- g_signal_new (I_("scroll_event"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GtkStatusIconClass, scroll_event),
- g_signal_accumulator_true_handled, NULL,
- _gtk_marshal_BOOLEAN__BOXED,
- G_TYPE_BOOLEAN, 1,
- GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
-
- /**
- * GtkStatusIcon::query-tooltip:
- * @status_icon: the object which received the signal
- * @x: the x coordinate of the cursor position where the request has been
- * emitted, relative to @status_icon
- * @y: the y coordinate of the cursor position where the request has been
- * emitted, relative to @status_icon
- * @keyboard_mode: %TRUE if the tooltip was trigged using the keyboard
- * @tooltip: a #GtkTooltip
- *
- * Emitted when the hover timeout has expired with the
- * cursor hovering above @status_icon; or emitted when @status_icon got
- * focus in keyboard mode.
- *
- * Using the given coordinates, the signal handler should determine
- * whether a tooltip should be shown for @status_icon. If this is
- * the case %TRUE should be returned, %FALSE otherwise. Note that if
- * @keyboard_mode is %TRUE, the values of @x and @y are undefined and
- * should not be used.
- *
- * The signal handler is free to manipulate @tooltip with the therefore
- * destined function calls.
- *
- * Whether this signal is emitted is platform-dependent.
- * For plain text tooltips, use #GtkStatusIcon:tooltip-text in preference.
- *
- * Returns: %TRUE if @tooltip should be shown right now, %FALSE otherwise.
- *
- * Since: 2.16
- */
- status_icon_signals [QUERY_TOOLTIP_SIGNAL] =
- g_signal_new (I_("query_tooltip"),
- G_TYPE_FROM_CLASS (gobject_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GtkStatusIconClass, query_tooltip),
- g_signal_accumulator_true_handled, NULL,
- _gtk_marshal_BOOLEAN__INT_INT_BOOLEAN_OBJECT,
- G_TYPE_BOOLEAN, 4,
- G_TYPE_INT,
- G_TYPE_INT,
- G_TYPE_BOOLEAN,
- GTK_TYPE_TOOLTIP);
-}
-
-#ifdef GDK_WINDOWING_WIN32
-
-static void
-build_button_event (GtkStatusIconPrivate *priv,
- GdkEventButton *e,
- guint button)
-{
- POINT pos;
- GdkRectangle monitor0;
-
- /* We know that gdk/win32 puts the primary monitor at index 0 */
- gdk_screen_get_monitor_geometry (gdk_screen_get_default (), 0, &monitor0);
- e->window = g_object_ref (gdk_get_default_root_window ());
- e->send_event = TRUE;
- e->time = GetTickCount ();
- GetCursorPos (&pos);
- priv->last_click_x = e->x = pos.x + monitor0.x;
- priv->last_click_y = e->y = pos.y + monitor0.y;
- e->axes = NULL;
- e->state = 0;
- e->button = button;
- //FIXME: e->device = gdk_display_get_default ()->core_pointer;
- e->x_root = e->x;
- e->y_root = e->y;
-}
-
-typedef struct
-{
- GtkStatusIcon *status_icon;
- GdkEventButton *event;
-} ButtonCallbackData;
-
-static gboolean
-button_callback (gpointer data)
-{
- ButtonCallbackData *bc = (ButtonCallbackData *) data;
-
- if (bc->event->type == GDK_BUTTON_PRESS)
- gtk_status_icon_button_press (bc->status_icon, bc->event);
- else
- gtk_status_icon_button_release (bc->status_icon, bc->event);
-
- gdk_event_free ((GdkEvent *) bc->event);
- g_free (data);
-
- return G_SOURCE_REMOVE;
-}
-
-static UINT taskbar_created_msg = 0;
-static GSList *status_icons = NULL;
-
-static LRESULT CALLBACK
-wndproc (HWND hwnd,
- UINT message,
- WPARAM wparam,
- LPARAM lparam)
-{
- if (message == taskbar_created_msg)
- {
- GSList *rover;
-
- for (rover = status_icons; rover != NULL; rover = rover->next)
- {
- GtkStatusIcon *status_icon = GTK_STATUS_ICON (rover->data);
- GtkStatusIconPrivate *priv = status_icon->priv;
-
- priv->nid.hWnd = hwnd;
- priv->nid.uID = GPOINTER_TO_UINT (status_icon);
- priv->nid.uCallbackMessage = WM_GTK_TRAY_NOTIFICATION;
- priv->nid.uFlags = NIF_MESSAGE;
-
- if (!Shell_NotifyIconW (NIM_ADD, &priv->nid))
- {
- g_warning (G_STRLOC ": Shell_NotifyIcon(NIM_ADD) failed");
- priv->nid.hWnd = NULL;
- continue;
- }
-
- gtk_status_icon_update_image (status_icon);
- }
- return 0;
- }
-
- if (message == WM_GTK_TRAY_NOTIFICATION)
- {
- ButtonCallbackData *bc;
- guint button;
-
- switch (lparam)
- {
- case WM_LBUTTONDOWN:
- button = 1;
- goto buttondown0;
-
- case WM_MBUTTONDOWN:
- button = 2;
- goto buttondown0;
-
- case WM_RBUTTONDOWN:
- button = 3;
- goto buttondown0;
-
- case WM_XBUTTONDOWN:
- if (HIWORD (wparam) == XBUTTON1)
- button = 4;
- else
- button = 5;
-
- buttondown0:
- bc = g_new (ButtonCallbackData, 1);
- bc->event = (GdkEventButton *) gdk_event_new (GDK_BUTTON_PRESS);
- bc->status_icon = GTK_STATUS_ICON (wparam);
- build_button_event (bc->status_icon->priv, bc->event, button);
- g_idle_add (button_callback, bc);
- break;
-
- case WM_LBUTTONUP:
- button = 1;
- goto buttonup0;
-
- case WM_MBUTTONUP:
- button = 2;
- goto buttonup0;
-
- case WM_RBUTTONUP:
- button = 3;
- goto buttonup0;
-
- case WM_XBUTTONUP:
- if (HIWORD (wparam) == XBUTTON1)
- button = 4;
- else
- button = 5;
-
- buttonup0:
- bc = g_new (ButtonCallbackData, 1);
- bc->event = (GdkEventButton *) gdk_event_new (GDK_BUTTON_RELEASE);
- bc->status_icon = GTK_STATUS_ICON (wparam);
- build_button_event (bc->status_icon->priv, bc->event, button);
- g_idle_add (button_callback, bc);
- break;
-
- default :
- break;
- }
- return 0;
- }
- else
- {
- return DefWindowProc (hwnd, message, wparam, lparam);
- }
-}
-
-static HWND
-create_tray_observer (void)
-{
- WNDCLASS wclass;
- static HWND hwnd = NULL;
- ATOM klass;
- HINSTANCE hmodule = GetModuleHandle (NULL);
-
- if (hwnd)
- return hwnd;
-
- taskbar_created_msg = RegisterWindowMessage("TaskbarCreated");
-
- memset (&wclass, 0, sizeof(WNDCLASS));
- wclass.lpszClassName = "gtkstatusicon-observer";
- wclass.lpfnWndProc = wndproc;
- wclass.hInstance = hmodule;
-
- klass = RegisterClass (&wclass);
- if (!klass)
- return NULL;
-
- hwnd = CreateWindow (MAKEINTRESOURCE (klass),
- NULL, WS_POPUP,
- 0, 0, 1, 1, NULL, NULL,
- hmodule, NULL);
- if (!hwnd)
- {
- UnregisterClass (MAKEINTRESOURCE(klass), hmodule);
- return NULL;
- }
-
- return hwnd;
-}
-
-#endif
-
-static void
-gtk_status_icon_init (GtkStatusIcon *status_icon)
-{
- GtkStatusIconPrivate *priv;
-
- priv = gtk_status_icon_get_instance_private (status_icon);
- status_icon->priv = priv;
-
- priv->icon_helper = _gtk_icon_helper_new ();
- _gtk_icon_helper_set_force_scale_pixbuf (priv->icon_helper, TRUE);
- priv->visible = TRUE;
-
-#ifdef GDK_WINDOWING_X11
- if (GDK_IS_X11_DISPLAY (gdk_display_get_default ()))
- {
- priv->size = 0;
- priv->tray_icon = GTK_WIDGET (_gtk_tray_icon_new (NULL));
-
- gtk_widget_add_events (GTK_WIDGET (priv->tray_icon),
- GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
- GDK_SCROLL_MASK);
-
- g_signal_connect_swapped (priv->tray_icon, "key-press-event",
- G_CALLBACK (gtk_status_icon_key_press), status_icon);
- g_signal_connect_swapped (priv->tray_icon, "popup-menu",
- G_CALLBACK (gtk_status_icon_popup_menu), status_icon);
- g_signal_connect_swapped (priv->tray_icon, "notify::embedded",
- G_CALLBACK (gtk_status_icon_embedded_changed), status_icon);
- g_signal_connect_swapped (priv->tray_icon, "notify::orientation",
- G_CALLBACK (gtk_status_icon_orientation_changed), status_icon);
- g_signal_connect_swapped (priv->tray_icon, "notify::padding",
- G_CALLBACK (gtk_status_icon_padding_changed), status_icon);
- g_signal_connect_swapped (priv->tray_icon, "notify::icon-size",
- G_CALLBACK (gtk_status_icon_icon_size_changed), status_icon);
- g_signal_connect_swapped (priv->tray_icon, "notify::fg-color",
- G_CALLBACK (gtk_status_icon_fg_changed), status_icon);
- g_signal_connect (priv->tray_icon, "notify::error-color",
- G_CALLBACK (gtk_status_icon_color_changed), status_icon);
- g_signal_connect (priv->tray_icon, "notify::warning-color",
- G_CALLBACK (gtk_status_icon_color_changed), status_icon);
- g_signal_connect (priv->tray_icon, "notify::success-color",
- G_CALLBACK (gtk_status_icon_color_changed), status_icon);
- g_signal_connect_swapped (priv->tray_icon, "button-press-event",
- G_CALLBACK (gtk_status_icon_button_press), status_icon);
- g_signal_connect_swapped (priv->tray_icon, "button-release-event",
- G_CALLBACK (gtk_status_icon_button_release), status_icon);
- g_signal_connect_swapped (priv->tray_icon, "scroll-event",
- G_CALLBACK (gtk_status_icon_scroll), status_icon);
- g_signal_connect_swapped (priv->tray_icon, "query-tooltip",
- G_CALLBACK (gtk_status_icon_query_tooltip), status_icon);
- g_signal_connect_swapped (priv->tray_icon, "screen-changed",
- G_CALLBACK (gtk_status_icon_screen_changed), status_icon);
- priv->image = gtk_image_new ();
- gtk_widget_set_can_focus (priv->image, TRUE);
- gtk_container_add (GTK_CONTAINER (priv->tray_icon), priv->image);
- gtk_widget_show (priv->image);
-
- /* Force-initialize the symbolic colors */
- g_object_notify (G_OBJECT (priv->tray_icon), "fg-color");
- g_object_notify (G_OBJECT (priv->tray_icon), "error-color");
- g_object_notify (G_OBJECT (priv->tray_icon), "warning-color");
- g_object_notify (G_OBJECT (priv->tray_icon), "success-color");
-
- g_signal_connect_swapped (priv->image, "size-allocate",
- G_CALLBACK (gtk_status_icon_size_allocate), status_icon);
- }
-#else /* !GDK_WINDOWING_X11 */
- priv->dummy_widget = gtk_label_new ("");
-#endif
-
-#ifdef GDK_WINDOWING_WIN32
-
- /* Get position and orientation of Windows taskbar. */
- {
- APPBARDATA abd;
-
- abd.cbSize = sizeof (abd);
- SHAppBarMessage (ABM_GETTASKBARPOS, &abd);
- if (abd.rc.bottom - abd.rc.top > abd.rc.right - abd.rc.left)
- priv->orientation = GTK_ORIENTATION_VERTICAL;
- else
- priv->orientation = GTK_ORIENTATION_HORIZONTAL;
-
- priv->taskbar_top = abd.rc.top;
- }
-
- priv->last_click_x = priv->last_click_y = 0;
-
- /* Are the system tray icons always 16 pixels square? */
- priv->size = 16;
-
- memset (&priv->nid, 0, sizeof (priv->nid));
-
- priv->nid.hWnd = create_tray_observer ();
- priv->nid.uID = GPOINTER_TO_UINT (status_icon);
- priv->nid.uCallbackMessage = WM_GTK_TRAY_NOTIFICATION;
- priv->nid.uFlags = NIF_MESSAGE;
-
- /* To help win7 identify the icon create it with an application "unique" tip */
- if (g_get_prgname ())
- {
- WCHAR *wcs = g_utf8_to_utf16 (g_get_prgname (), -1, NULL, NULL, NULL);
-
- priv->nid.uFlags |= NIF_TIP;
- wcsncpy (priv->nid.szTip, wcs, G_N_ELEMENTS (priv->nid.szTip) - 1);
- priv->nid.szTip[G_N_ELEMENTS (priv->nid.szTip) - 1] = 0;
- g_free (wcs);
- }
-
- if (!Shell_NotifyIconW (NIM_ADD, &priv->nid))
- {
- g_warning (G_STRLOC ": Shell_NotifyIcon(NIM_ADD) failed");
- priv->nid.hWnd = NULL;
- }
-
- status_icons = g_slist_append (status_icons, status_icon);
-
-#endif
-
-#ifdef GDK_WINDOWING_QUARTZ
- QUARTZ_POOL_ALLOC;
-
- priv->status_item = [[GtkQuartzStatusIcon alloc] initWithStatusIcon:status_icon];
- priv->size = [priv->status_item getHeight];
-
- QUARTZ_POOL_RELEASE;
-
-#endif
-}
-
-static void
-gtk_status_icon_constructed (GObject *object)
-{
- G_OBJECT_CLASS (gtk_status_icon_parent_class)->constructed (object);
-
-#ifdef GDK_WINDOWING_X11
- {
- GtkStatusIcon *status_icon = GTK_STATUS_ICON (object);
- GtkStatusIconPrivate *priv = status_icon->priv;
-
- if (priv->visible && priv->tray_icon)
- gtk_widget_show (priv->tray_icon);
- }
-#endif
-}
-
-static void
-gtk_status_icon_finalize (GObject *object)
-{
- GtkStatusIcon *status_icon = GTK_STATUS_ICON (object);
- GtkStatusIconPrivate *priv = status_icon->priv;
-
- gtk_status_icon_reset_image_data (status_icon);
- g_clear_object (&priv->icon_helper);
-
-#ifdef GDK_WINDOWING_X11
- if (priv->tray_icon)
- {
- g_signal_handlers_disconnect_by_func (priv->tray_icon,
- gtk_status_icon_key_press, status_icon);
- g_signal_handlers_disconnect_by_func (priv->tray_icon,
- gtk_status_icon_popup_menu, status_icon);
- g_signal_handlers_disconnect_by_func (priv->tray_icon,
- gtk_status_icon_embedded_changed, status_icon);
- g_signal_handlers_disconnect_by_func (priv->tray_icon,
- gtk_status_icon_orientation_changed, status_icon);
- g_signal_handlers_disconnect_by_func (priv->tray_icon,
- gtk_status_icon_padding_changed, status_icon);
- g_signal_handlers_disconnect_by_func (priv->tray_icon,
- gtk_status_icon_icon_size_changed, status_icon);
- g_signal_handlers_disconnect_by_func (priv->tray_icon,
- gtk_status_icon_fg_changed, status_icon);
- g_signal_handlers_disconnect_by_func (priv->tray_icon,
- gtk_status_icon_color_changed, status_icon);
- g_signal_handlers_disconnect_by_func (priv->tray_icon,
- gtk_status_icon_button_press, status_icon);
- g_signal_handlers_disconnect_by_func (priv->tray_icon,
- gtk_status_icon_button_release, status_icon);
- g_signal_handlers_disconnect_by_func (priv->tray_icon,
- gtk_status_icon_scroll, status_icon);
- g_signal_handlers_disconnect_by_func (priv->tray_icon,
- gtk_status_icon_query_tooltip, status_icon);
- g_signal_handlers_disconnect_by_func (priv->tray_icon,
- gtk_status_icon_screen_changed, status_icon);
- gtk_widget_destroy (priv->image);
- gtk_widget_destroy (priv->tray_icon);
- }
-#else /* !GDK_WINDOWING_X11 */
- gtk_widget_destroy (priv->dummy_widget);
-#endif
-
-#ifdef GDK_WINDOWING_WIN32
- if (priv->nid.hWnd != NULL && priv->visible)
- Shell_NotifyIconW (NIM_DELETE, &priv->nid);
- if (priv->nid.hIcon)
- DestroyIcon (priv->nid.hIcon);
- g_free (priv->tooltip_text);
-
- status_icons = g_slist_remove (status_icons, status_icon);
-#endif
-
-#ifdef GDK_WINDOWING_QUARTZ
- QUARTZ_POOL_ALLOC;
- [priv->status_item release];
- QUARTZ_POOL_RELEASE;
- g_free (priv->tooltip_text);
-#endif
-
- G_OBJECT_CLASS (gtk_status_icon_parent_class)->finalize (object);
-}
-
-static void
-gtk_status_icon_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GtkStatusIcon *status_icon = GTK_STATUS_ICON (object);
-
- switch (prop_id)
- {
- case PROP_PIXBUF:
- gtk_status_icon_set_from_pixbuf (status_icon, g_value_get_object (value));
- break;
- case PROP_FILE:
- gtk_status_icon_set_from_file (status_icon, g_value_get_string (value));
- break;
- case PROP_STOCK:
- G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
- gtk_status_icon_set_from_stock (status_icon, g_value_get_string (value));
- G_GNUC_END_IGNORE_DEPRECATIONS;
- break;
- case PROP_ICON_NAME:
- gtk_status_icon_set_from_icon_name (status_icon, g_value_get_string (value));
- break;
- case PROP_GICON:
- gtk_status_icon_set_from_gicon (status_icon, g_value_get_object (value));
- break;
- case PROP_SCREEN:
- gtk_status_icon_set_screen (status_icon, g_value_get_object (value));
- break;
- case PROP_VISIBLE:
- gtk_status_icon_set_visible (status_icon, g_value_get_boolean (value));
- break;
- case PROP_HAS_TOOLTIP:
- gtk_status_icon_set_has_tooltip (status_icon, g_value_get_boolean (value));
- break;
- case PROP_TOOLTIP_TEXT:
- gtk_status_icon_set_tooltip_text (status_icon, g_value_get_string (value));
- break;
- case PROP_TOOLTIP_MARKUP:
- gtk_status_icon_set_tooltip_markup (status_icon, g_value_get_string (value));
- break;
- case PROP_TITLE:
- gtk_status_icon_set_title (status_icon, g_value_get_string (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gtk_status_icon_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GtkStatusIcon *status_icon = GTK_STATUS_ICON (object);
-
- switch (prop_id)
- {
- case PROP_PIXBUF:
- g_value_set_object (value, gtk_status_icon_get_pixbuf (status_icon));
- break;
- case PROP_STOCK:
- G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
- g_value_set_string (value, gtk_status_icon_get_stock (status_icon));
- G_GNUC_END_IGNORE_DEPRECATIONS;
- break;
- case PROP_ICON_NAME:
- g_value_set_string (value, gtk_status_icon_get_icon_name (status_icon));
- break;
- case PROP_GICON:
- g_value_set_object (value, gtk_status_icon_get_gicon (status_icon));
- break;
- case PROP_STORAGE_TYPE:
- g_value_set_enum (value, gtk_status_icon_get_storage_type (status_icon));
- break;
- case PROP_SIZE:
- g_value_set_int (value, gtk_status_icon_get_size (status_icon));
- break;
- case PROP_SCREEN:
- g_value_set_object (value, gtk_status_icon_get_screen (status_icon));
- break;
- case PROP_VISIBLE:
- g_value_set_boolean (value, gtk_status_icon_get_visible (status_icon));
- break;
- case PROP_EMBEDDED:
- g_value_set_boolean (value, gtk_status_icon_is_embedded (status_icon));
- break;
- case PROP_ORIENTATION:
-#ifdef GDK_WINDOWING_X11
- if (status_icon->priv->tray_icon)
- g_value_set_enum (value, _gtk_tray_icon_get_orientation (GTK_TRAY_ICON (status_icon->priv->tray_icon)));
- else
- g_value_set_enum (value, GTK_ORIENTATION_HORIZONTAL);
-#endif
-#ifdef GDK_WINDOWING_WIN32
- g_value_set_enum (value, status_icon->priv->orientation);
-#endif
- break;
- case PROP_HAS_TOOLTIP:
- g_value_set_boolean (value, gtk_status_icon_get_has_tooltip (status_icon));
- break;
- case PROP_TOOLTIP_TEXT:
- g_value_set_string (value, gtk_status_icon_get_tooltip_text (status_icon));
- break;
- case PROP_TOOLTIP_MARKUP:
- g_value_set_string (value, gtk_status_icon_get_tooltip_markup (status_icon));
- break;
- case PROP_TITLE:
- g_value_set_string (value, gtk_status_icon_get_title (status_icon));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/**
- * gtk_status_icon_new:
- *
- * Creates an empty status icon object.
- *
- * Returns: a new #GtkStatusIcon
- *
- * Since: 2.10
- **/
-GtkStatusIcon *
-gtk_status_icon_new (void)
-{
- return g_object_new (GTK_TYPE_STATUS_ICON, NULL);
-}
-
-/**
- * gtk_status_icon_new_from_pixbuf:
- * @pixbuf: a #GdkPixbuf
- *
- * Creates a status icon displaying @pixbuf.
- *
- * The image will be scaled down to fit in the available
- * space in the notification area, if necessary.
- *
- * Returns: a new #GtkStatusIcon
- *
- * Since: 2.10
- **/
-GtkStatusIcon *
-gtk_status_icon_new_from_pixbuf (GdkPixbuf *pixbuf)
-{
- return g_object_new (GTK_TYPE_STATUS_ICON,
- "pixbuf", pixbuf,
- NULL);
-}
-
-/**
- * gtk_status_icon_new_from_file:
- * @filename: (type filename): a filename
- *
- * Creates a status icon displaying the file @filename.
- *
- * The image will be scaled down to fit in the available
- * space in the notification area, if necessary.
- *
- * Returns: a new #GtkStatusIcon
- *
- * Since: 2.10
- **/
-GtkStatusIcon *
-gtk_status_icon_new_from_file (const gchar *filename)
-{
- return g_object_new (GTK_TYPE_STATUS_ICON,
- "file", filename,
- NULL);
-}
-
-/**
- * gtk_status_icon_new_from_stock:
- * @stock_id: a stock icon id
- *
- * Creates a status icon displaying a stock icon. Sample stock icon
- * names are #GTK_STOCK_OPEN, #GTK_STOCK_QUIT. You can register your
- * own stock icon names, see gtk_icon_factory_add_default() and
- * gtk_icon_factory_add().
- *
- * Returns: a new #GtkStatusIcon
- *
- * Since: 2.10
- *
- * Deprecated: 3.10: Use gtk_status_icon_new_from_icon_name() instead.
- **/
-GtkStatusIcon *
-gtk_status_icon_new_from_stock (const gchar *stock_id)
-{
- return g_object_new (GTK_TYPE_STATUS_ICON,
- "stock", stock_id,
- NULL);
-}
-
-/**
- * gtk_status_icon_new_from_icon_name:
- * @icon_name: an icon name
- *
- * Creates a status icon displaying an icon from the current icon theme.
- * If the current icon theme is changed, the icon will be updated
- * appropriately.
- *
- * Returns: a new #GtkStatusIcon
- *
- * Since: 2.10
- **/
-GtkStatusIcon *
-gtk_status_icon_new_from_icon_name (const gchar *icon_name)
-{
- return g_object_new (GTK_TYPE_STATUS_ICON,
- "icon-name", icon_name,
- NULL);
-}
-
-/**
- * gtk_status_icon_new_from_gicon:
- * @icon: a #GIcon
- *
- * Creates a status icon displaying a #GIcon. If the icon is a
- * themed icon, it will be updated when the theme changes.
- *
- * Returns: a new #GtkStatusIcon
- *
- * Since: 2.14
- **/
-GtkStatusIcon *
-gtk_status_icon_new_from_gicon (GIcon *icon)
-{
- return g_object_new (GTK_TYPE_STATUS_ICON,
- "gicon", icon,
- NULL);
-}
-
-static void
-emit_activate_signal (GtkStatusIcon *status_icon)
-{
- g_signal_emit (status_icon,
- status_icon_signals [ACTIVATE_SIGNAL], 0);
-}
-
-static void
-emit_popup_menu_signal (GtkStatusIcon *status_icon,
- guint button,
- guint32 activate_time)
-{
- g_signal_emit (status_icon,
- status_icon_signals [POPUP_MENU_SIGNAL], 0,
- button,
- activate_time);
-}
-
-#ifdef GDK_WINDOWING_X11
-
-static gboolean
-emit_size_changed_signal (GtkStatusIcon *status_icon,
- gint size)
-{
- gboolean handled = FALSE;
-
- g_signal_emit (status_icon,
- status_icon_signals [SIZE_CHANGED_SIGNAL], 0,
- size,
- &handled);
-
- return handled;
-}
-
-#endif
-
-/* rounds the pixel size to the nearest size avaiable in the theme */
-static gint
-round_pixel_size (GtkWidget *widget,
- gint pixel_size)
-{
- GtkIconSize s;
- gint w, h, d, dist, size;
-
- dist = G_MAXINT;
- size = 0;
-
- for (s = GTK_ICON_SIZE_MENU; s <= GTK_ICON_SIZE_DIALOG; s++)
- {
- if (gtk_icon_size_lookup (s, &w, &h))
- {
- d = MAX (abs (pixel_size - w), abs (pixel_size - h));
- if (d < dist)
- {
- dist = d;
- size = MAX (w, h);
- }
- }
- }
-
- return size;
-}
-
-static void
-gtk_status_icon_update_image (GtkStatusIcon *status_icon)
-{
- GtkStatusIconPrivate *priv = status_icon->priv;
-#ifdef GDK_WINDOWING_WIN32
- HICON prev_hicon;
-#endif
- GtkStyleContext *context;
- GtkWidget *widget;
- GdkPixbuf *pixbuf;
- gint round_size;
-
-#ifdef GDK_WINDOWING_X11
- widget = priv->image;
-#else
- widget = priv->dummy_widget;
-#endif
-
- if (widget == NULL)
- return;
-
- context = gtk_widget_get_style_context (widget);
- round_size = round_pixel_size (widget, priv->size);
-
- _gtk_icon_helper_set_pixel_size (priv->icon_helper, round_size);
- pixbuf = _gtk_icon_helper_ensure_pixbuf (priv->icon_helper, context);
-
- if (pixbuf != NULL)
- {
-#ifdef GDK_WINDOWING_X11
- gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), pixbuf);
-#endif
-#ifdef GDK_WINDOWING_WIN32
- prev_hicon = priv->nid.hIcon;
- priv->nid.hIcon = gdk_win32_pixbuf_to_hicon_libgtk_only (pixbuf);
- priv->nid.uFlags |= NIF_ICON;
- if (priv->nid.hWnd != NULL && priv->visible)
- if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
- g_warning (G_STRLOC ": Shell_NotifyIcon(NIM_MODIFY) failed");
- if (prev_hicon)
- DestroyIcon (prev_hicon);
-#endif
-#ifdef GDK_WINDOWING_QUARTZ
- QUARTZ_POOL_ALLOC;
- [priv->status_item setImage:pixbuf];
- QUARTZ_POOL_RELEASE;
-#endif
- }
- else
- {
-#ifdef GDK_WINDOWING_X11
- gtk_image_set_from_pixbuf (GTK_IMAGE (priv->image), NULL);
-#endif
-#ifdef GDK_WINDOWING_WIN32
- priv->nid.uFlags &= ~NIF_ICON;
- if (priv->nid.hWnd != NULL && priv->visible)
- if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
- g_warning (G_STRLOC ": Shell_NotifyIcon(NIM_MODIFY) failed");
-#endif
-#ifdef GDK_WINDOWING_QUARTZ
- [priv->status_item setImage:NULL];
-#endif
- }
-
- g_clear_object (&pixbuf);
-}
-
-#ifdef GDK_WINDOWING_X11
-
-static void
-gtk_status_icon_size_allocate (GtkStatusIcon *status_icon,
- GtkAllocation *allocation)
-{
- GtkStatusIconPrivate *priv = status_icon->priv;
- GtkOrientation orientation;
- gint size;
-
- orientation = _gtk_tray_icon_get_orientation (GTK_TRAY_ICON (priv->tray_icon));
-
- if (orientation == GTK_ORIENTATION_HORIZONTAL)
- size = allocation->height;
- else
- size = allocation->width;
-
- if (priv->size != size)
- {
- priv->size = size;
-
- g_object_notify (G_OBJECT (status_icon), "size");
-
- if (!emit_size_changed_signal (status_icon, size))
- gtk_status_icon_update_image (status_icon);
- }
-}
-
-static void
-gtk_status_icon_screen_changed (GtkStatusIcon *status_icon,
- GdkScreen *old_screen)
-{
- GtkStatusIconPrivate *priv = status_icon->priv;
-
- if (gtk_widget_get_screen (priv->tray_icon) != old_screen)
- {
- g_object_notify (G_OBJECT (status_icon), "screen");
- }
-}
-
-static void
-gtk_status_icon_padding_changed (GtkStatusIcon *status_icon)
-{
- GtkStatusIconPrivate *priv = status_icon->priv;
- GtkOrientation orientation;
- gint padding;
-
- orientation = _gtk_tray_icon_get_orientation (GTK_TRAY_ICON (priv->tray_icon));
- padding = _gtk_tray_icon_get_padding (GTK_TRAY_ICON (priv->tray_icon));
-
- if (orientation == GTK_ORIENTATION_HORIZONTAL)
- {
- gtk_widget_set_margin_start (priv->image, padding);
- gtk_widget_set_margin_end (priv->image, padding);
- }
- else
- {
- gtk_widget_set_margin_bottom (priv->image, padding);
- gtk_widget_set_margin_top (priv->image, padding);
- }
-}
-
-static void
-gtk_status_icon_icon_size_changed (GtkStatusIcon *status_icon)
-{
- GtkStatusIconPrivate *priv = status_icon->priv;
- gint icon_size;
-
- icon_size = _gtk_tray_icon_get_icon_size (GTK_TRAY_ICON (priv->tray_icon));
-
- if (icon_size != 0)
- gtk_image_set_pixel_size (GTK_IMAGE (priv->image), icon_size);
- else
- gtk_image_set_pixel_size (GTK_IMAGE (priv->image), -1);
-}
-
-static void
-gtk_status_icon_embedded_changed (GtkStatusIcon *status_icon)
-{
- gtk_status_icon_padding_changed (status_icon);
- gtk_status_icon_icon_size_changed (status_icon);
- g_object_notify (G_OBJECT (status_icon), "embedded");
-}
-
-static void
-gtk_status_icon_orientation_changed (GtkStatusIcon *status_icon)
-{
- gtk_status_icon_padding_changed (status_icon);
- g_object_notify (G_OBJECT (status_icon), "orientation");
-}
-
-static void
-gtk_status_icon_fg_changed (GtkStatusIcon *status_icon)
-{
- GtkStatusIconPrivate *priv = status_icon->priv;
- GdkRGBA *rgba;
-
- g_object_get (priv->tray_icon, "fg-color", &rgba, NULL);
-
- gtk_widget_override_color (priv->image, GTK_STATE_FLAG_NORMAL, rgba);
-
- gdk_rgba_free (rgba);
-}
-
-static void
-gtk_status_icon_color_changed (GtkTrayIcon *tray,
- GParamSpec *pspec,
- GtkStatusIcon *status_icon)
-{
- GtkStatusIconPrivate *priv = status_icon->priv;
- const gchar *name;
-
- switch (pspec->name[0])
- {
- case 'e':
- name = "error";
- break;
- case 'w':
- name = "warning";
- break;
- case 's':
- name = "success";
- break;
- default:
- name = NULL;
- break;
- }
-
- if (name)
- {
- GdkRGBA rgba;
-
- g_object_get (priv->tray_icon, pspec->name, &rgba, NULL);
-
- rgba.alpha = 1;
-
- gtk_widget_override_symbolic_color (priv->image, name, &rgba);
- }
-}
-
-static gboolean
-gtk_status_icon_key_press (GtkStatusIcon *status_icon,
- GdkEventKey *event)
-{
- guint state, keyval;
-
- state = event->state & gtk_accelerator_get_default_mod_mask ();
- keyval = event->keyval;
- if (state == 0 &&
- (keyval == GDK_KEY_Return ||
- keyval == GDK_KEY_KP_Enter ||
- keyval == GDK_KEY_ISO_Enter ||
- keyval == GDK_KEY_space ||
- keyval == GDK_KEY_KP_Space))
- {
- emit_activate_signal (status_icon);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-gtk_status_icon_popup_menu (GtkStatusIcon *status_icon)
-{
- emit_popup_menu_signal (status_icon, 0, gtk_get_current_event_time ());
-}
-
-#endif /* GDK_WINDOWING_X11 */
-
-static gboolean
-gtk_status_icon_button_press (GtkStatusIcon *status_icon,
- GdkEventButton *event)
-{
- gboolean handled = FALSE;
-
- g_signal_emit (status_icon,
- status_icon_signals [BUTTON_PRESS_EVENT_SIGNAL], 0,
- event, &handled);
- if (handled)
- return TRUE;
-
- if (gdk_event_triggers_context_menu ((GdkEvent *) event))
- {
- emit_popup_menu_signal (status_icon, event->button, event->time);
- return TRUE;
- }
- else if (event->button == GDK_BUTTON_PRIMARY && event->type == GDK_BUTTON_PRESS)
- {
- emit_activate_signal (status_icon);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
-gtk_status_icon_button_release (GtkStatusIcon *status_icon,
- GdkEventButton *event)
-{
- gboolean handled = FALSE;
- g_signal_emit (status_icon,
- status_icon_signals [BUTTON_RELEASE_EVENT_SIGNAL], 0,
- event, &handled);
- return handled;
-}
-
-#ifdef GDK_WINDOWING_X11
-
-static gboolean
-gtk_status_icon_scroll (GtkStatusIcon *status_icon,
- GdkEventScroll *event)
-{
- gboolean handled = FALSE;
- g_signal_emit (status_icon,
- status_icon_signals [SCROLL_EVENT_SIGNAL], 0,
- event, &handled);
- return handled;
-}
-
-static gboolean
-gtk_status_icon_query_tooltip (GtkStatusIcon *status_icon,
- gint x,
- gint y,
- gboolean keyboard_tip,
- GtkTooltip *tooltip)
-{
- gboolean handled = FALSE;
- g_signal_emit (status_icon,
- status_icon_signals [QUERY_TOOLTIP_SIGNAL], 0,
- x, y, keyboard_tip, tooltip, &handled);
- return handled;
-}
-
-#endif /* GDK_WINDOWING_X11 */
-
-static void
-gtk_status_icon_reset_image_data (GtkStatusIcon *status_icon)
-{
- GtkStatusIconPrivate *priv = status_icon->priv;
- GtkImageType storage_type = _gtk_icon_helper_get_storage_type (priv->icon_helper);
-
- switch (storage_type)
- {
- case GTK_IMAGE_PIXBUF:
- g_object_notify (G_OBJECT (status_icon), "pixbuf");
- break;
- case GTK_IMAGE_STOCK:
- g_object_notify (G_OBJECT (status_icon), "stock");
- break;
- case GTK_IMAGE_ICON_NAME:
- g_object_notify (G_OBJECT (status_icon), "icon-name");
- break;
- case GTK_IMAGE_GICON:
- g_object_notify (G_OBJECT (status_icon), "gicon");
- break;
- case GTK_IMAGE_EMPTY:
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-
- _gtk_icon_helper_clear (priv->icon_helper);
- g_object_notify (G_OBJECT (status_icon), "storage-type");
-}
-
-static void
-gtk_status_icon_set_image (GtkStatusIcon *status_icon,
- GtkImageType storage_type,
- gpointer data)
-{
- GtkStatusIconPrivate *priv = status_icon->priv;
-
- g_object_freeze_notify (G_OBJECT (status_icon));
-
- gtk_status_icon_reset_image_data (status_icon);
-
- g_object_notify (G_OBJECT (status_icon), "storage-type");
-
- /* the icon size we pass here doesn't really matter, since
- * we force a pixel size before doing the actual rendering anyway.
- */
- switch (storage_type)
- {
- case GTK_IMAGE_PIXBUF:
- _gtk_icon_helper_set_pixbuf (priv->icon_helper, data);
- g_object_notify (G_OBJECT (status_icon), "pixbuf");
- break;
- case GTK_IMAGE_STOCK:
- _gtk_icon_helper_set_stock_id (priv->icon_helper, data, GTK_ICON_SIZE_SMALL_TOOLBAR);
- g_object_notify (G_OBJECT (status_icon), "stock");
- break;
- case GTK_IMAGE_ICON_NAME:
- _gtk_icon_helper_set_icon_name (priv->icon_helper, data, GTK_ICON_SIZE_SMALL_TOOLBAR);
- g_object_notify (G_OBJECT (status_icon), "icon-name");
- break;
- case GTK_IMAGE_GICON:
- _gtk_icon_helper_set_gicon (priv->icon_helper, data, GTK_ICON_SIZE_SMALL_TOOLBAR);
- g_object_notify (G_OBJECT (status_icon), "gicon");
- break;
- default:
- g_warning ("Image type %u not handled by GtkStatusIcon", storage_type);
- }
-
- g_object_thaw_notify (G_OBJECT (status_icon));
-
- gtk_status_icon_update_image (status_icon);
-}
-
-/**
- * gtk_status_icon_set_from_pixbuf:
- * @status_icon: a #GtkStatusIcon
- * @pixbuf: (allow-none): a #GdkPixbuf or %NULL
- *
- * Makes @status_icon display @pixbuf.
- * See gtk_status_icon_new_from_pixbuf() for details.
- *
- * Since: 2.10
- **/
-void
-gtk_status_icon_set_from_pixbuf (GtkStatusIcon *status_icon,
- GdkPixbuf *pixbuf)
-{
- g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
- g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
-
- gtk_status_icon_set_image (status_icon, GTK_IMAGE_PIXBUF,
- (gpointer) pixbuf);
-}
-
-/**
- * gtk_status_icon_set_from_file:
- * @status_icon: a #GtkStatusIcon
- * @filename: (type filename): a filename
- *
- * Makes @status_icon display the file @filename.
- * See gtk_status_icon_new_from_file() for details.
- *
- * Since: 2.10
- **/
-void
-gtk_status_icon_set_from_file (GtkStatusIcon *status_icon,
- const gchar *filename)
-{
- GdkPixbuf *pixbuf;
-
- g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
- g_return_if_fail (filename != NULL);
-
- pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
-
- gtk_status_icon_set_from_pixbuf (status_icon, pixbuf);
-
- if (pixbuf)
- g_object_unref (pixbuf);
-}
-
-/**
- * gtk_status_icon_set_from_stock:
- * @status_icon: a #GtkStatusIcon
- * @stock_id: a stock icon id
- *
- * Makes @status_icon display the stock icon with the id @stock_id.
- * See gtk_status_icon_new_from_stock() for details.
- *
- * Since: 2.10
- *
- * Deprecated: 3.10: Use gtk_status_icon_set_from_icon_name() instead.
- **/
-void
-gtk_status_icon_set_from_stock (GtkStatusIcon *status_icon,
- const gchar *stock_id)
-{
- g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
- g_return_if_fail (stock_id != NULL);
-
- gtk_status_icon_set_image (status_icon, GTK_IMAGE_STOCK,
- (gpointer) stock_id);
-}
-
-/**
- * gtk_status_icon_set_from_icon_name:
- * @status_icon: a #GtkStatusIcon
- * @icon_name: an icon name
- *
- * Makes @status_icon display the icon named @icon_name from the
- * current icon theme.
- * See gtk_status_icon_new_from_icon_name() for details.
- *
- * Since: 2.10
- **/
-void
-gtk_status_icon_set_from_icon_name (GtkStatusIcon *status_icon,
- const gchar *icon_name)
-{
- g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
- g_return_if_fail (icon_name != NULL);
-
- gtk_status_icon_set_image (status_icon, GTK_IMAGE_ICON_NAME,
- (gpointer) icon_name);
-}
-
-/**
- * gtk_status_icon_set_from_gicon:
- * @status_icon: a #GtkStatusIcon
- * @icon: a GIcon
- *
- * Makes @status_icon display the #GIcon.
- * See gtk_status_icon_new_from_gicon() for details.
- *
- * Since: 2.14
- **/
-void
-gtk_status_icon_set_from_gicon (GtkStatusIcon *status_icon,
- GIcon *icon)
-{
- g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
- g_return_if_fail (icon != NULL);
-
- gtk_status_icon_set_image (status_icon, GTK_IMAGE_GICON,
- (gpointer) icon);
-}
-
-/**
- * gtk_status_icon_get_storage_type:
- * @status_icon: a #GtkStatusIcon
- *
- * Gets the type of representation being used by the #GtkStatusIcon
- * to store image data. If the #GtkStatusIcon has no image data,
- * the return value will be %GTK_IMAGE_EMPTY.
- *
- * Returns: the image representation being used
- *
- * Since: 2.10
- **/
-GtkImageType
-gtk_status_icon_get_storage_type (GtkStatusIcon *status_icon)
-{
- g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), GTK_IMAGE_EMPTY);
-
- return _gtk_icon_helper_get_storage_type (status_icon->priv->icon_helper);
-}
-/**
- * gtk_status_icon_get_pixbuf:
- * @status_icon: a #GtkStatusIcon
- *
- * Gets the #GdkPixbuf being displayed by the #GtkStatusIcon.
- * The storage type of the status icon must be %GTK_IMAGE_EMPTY or
- * %GTK_IMAGE_PIXBUF (see gtk_status_icon_get_storage_type()).
- * The caller of this function does not own a reference to the
- * returned pixbuf.
- *
- * Returns: (transfer none): the displayed pixbuf,
- * or %NULL if the image is empty.
- *
- * Since: 2.10
- **/
-GdkPixbuf *
-gtk_status_icon_get_pixbuf (GtkStatusIcon *status_icon)
-{
- GtkStatusIconPrivate *priv;
-
- g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
-
- priv = status_icon->priv;
-
- return _gtk_icon_helper_peek_pixbuf (priv->icon_helper);
-}
-
-/**
- * gtk_status_icon_get_stock:
- * @status_icon: a #GtkStatusIcon
- *
- * Gets the id of the stock icon being displayed by the #GtkStatusIcon.
- * The storage type of the status icon must be %GTK_IMAGE_EMPTY or
- * %GTK_IMAGE_STOCK (see gtk_status_icon_get_storage_type()).
- * The returned string is owned by the #GtkStatusIcon and should not
- * be freed or modified.
- *
- * Returns: stock id of the displayed stock icon,
- * or %NULL if the image is empty.
- *
- * Since: 2.10
- *
- * Deprecated: 3.10: Use gtk_status_icon_get_icon_name() instead.
- **/
-const gchar *
-gtk_status_icon_get_stock (GtkStatusIcon *status_icon)
-{
- GtkStatusIconPrivate *priv;
-
- g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
-
- priv = status_icon->priv;
-
- return _gtk_icon_helper_get_stock_id (priv->icon_helper);
-}
-
-/**
- * gtk_status_icon_get_icon_name:
- * @status_icon: a #GtkStatusIcon
- *
- * Gets the name of the icon being displayed by the #GtkStatusIcon.
- * The storage type of the status icon must be %GTK_IMAGE_EMPTY or
- * %GTK_IMAGE_ICON_NAME (see gtk_status_icon_get_storage_type()).
- * The returned string is owned by the #GtkStatusIcon and should not
- * be freed or modified.
- *
- * Returns: name of the displayed icon, or %NULL if the image is empty.
- *
- * Since: 2.10
- **/
-const gchar *
-gtk_status_icon_get_icon_name (GtkStatusIcon *status_icon)
-{
- GtkStatusIconPrivate *priv;
-
- g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
-
- priv = status_icon->priv;
-
- return _gtk_icon_helper_get_icon_name (priv->icon_helper);
-}
-
-/**
- * gtk_status_icon_get_gicon:
- * @status_icon: a #GtkStatusIcon
- *
- * Retrieves the #GIcon being displayed by the #GtkStatusIcon.
- * The storage type of the status icon must be %GTK_IMAGE_EMPTY or
- * %GTK_IMAGE_GICON (see gtk_status_icon_get_storage_type()).
- * The caller of this function does not own a reference to the
- * returned #GIcon.
- *
- * If this function fails, @icon is left unchanged;
- *
- * Returns: (transfer none): the displayed icon, or %NULL if the image is empty
- *
- * Since: 2.14
- **/
-GIcon *
-gtk_status_icon_get_gicon (GtkStatusIcon *status_icon)
-{
- GtkStatusIconPrivate *priv;
-
- g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
-
- priv = status_icon->priv;
-
- return _gtk_icon_helper_peek_gicon (priv->icon_helper);
-}
-
-/**
- * gtk_status_icon_get_size:
- * @status_icon: a #GtkStatusIcon
- *
- * Gets the size in pixels that is available for the image.
- * Stock icons and named icons adapt their size automatically
- * if the size of the notification area changes. For other
- * storage types, the size-changed signal can be used to
- * react to size changes.
- *
- * Note that the returned size is only meaningful while the
- * status icon is embedded (see gtk_status_icon_is_embedded()).
- *
- * Returns: the size that is available for the image
- *
- * Since: 2.10
- **/
-gint
-gtk_status_icon_get_size (GtkStatusIcon *status_icon)
-{
- g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), 0);
-
- return status_icon->priv->size;
-}
-
-/**
- * gtk_status_icon_set_screen:
- * @status_icon: a #GtkStatusIcon
- * @screen: a #GdkScreen
- *
- * Sets the #GdkScreen where @status_icon is displayed; if
- * the icon is already mapped, it will be unmapped, and
- * then remapped on the new screen.
- *
- * Since: 2.12
- */
-void
-gtk_status_icon_set_screen (GtkStatusIcon *status_icon,
- GdkScreen *screen)
-{
- g_return_if_fail (GDK_IS_SCREEN (screen));
-
-#ifdef GDK_WINDOWING_X11
- if (status_icon->priv->tray_icon)
- gtk_window_set_screen (GTK_WINDOW (status_icon->priv->tray_icon), screen);
-#endif
-}
-
-/**
- * gtk_status_icon_get_screen:
- * @status_icon: a #GtkStatusIcon
- *
- * Returns the #GdkScreen associated with @status_icon.
- *
- * Returns: (transfer none): a #GdkScreen.
- *
- * Since: 2.12
- */
-GdkScreen *
-gtk_status_icon_get_screen (GtkStatusIcon *status_icon)
-{
- g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
-
-#ifdef GDK_WINDOWING_X11
- if (status_icon->priv->tray_icon)
- return gtk_window_get_screen (GTK_WINDOW (status_icon->priv->tray_icon));
- else
-#endif
- return gdk_screen_get_default ();
-}
-
-/**
- * gtk_status_icon_set_visible:
- * @status_icon: a #GtkStatusIcon
- * @visible: %TRUE to show the status icon, %FALSE to hide it
- *
- * Shows or hides a status icon.
- *
- * Since: 2.10
- **/
-void
-gtk_status_icon_set_visible (GtkStatusIcon *status_icon,
- gboolean visible)
-{
- GtkStatusIconPrivate *priv;
-
- g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
-
- priv = status_icon->priv;
-
- visible = visible != FALSE;
-
- if (priv->visible != visible)
- {
- priv->visible = visible;
-
-#ifdef GDK_WINDOWING_X11
- if (priv->tray_icon)
- {
- if (visible)
- gtk_widget_show (priv->tray_icon);
- else if (gtk_widget_get_realized (priv->tray_icon))
- {
- gtk_widget_hide (priv->tray_icon);
- gtk_widget_unrealize (priv->tray_icon);
- }
- }
-#endif
-#ifdef GDK_WINDOWING_WIN32
- if (priv->nid.hWnd != NULL)
- {
- if (visible)
- Shell_NotifyIconW (NIM_ADD, &priv->nid);
- else
- Shell_NotifyIconW (NIM_DELETE, &priv->nid);
- }
-#endif
-#ifdef GDK_WINDOWING_QUARTZ
- QUARTZ_POOL_ALLOC;
- [priv->status_item setVisible:visible];
- QUARTZ_POOL_RELEASE;
-#endif
- g_object_notify (G_OBJECT (status_icon), "visible");
- }
-}
-
-/**
- * gtk_status_icon_get_visible:
- * @status_icon: a #GtkStatusIcon
- *
- * Returns whether the status icon is visible or not.
- * Note that being visible does not guarantee that
- * the user can actually see the icon, see also
- * gtk_status_icon_is_embedded().
- *
- * Returns: %TRUE if the status icon is visible
- *
- * Since: 2.10
- **/
-gboolean
-gtk_status_icon_get_visible (GtkStatusIcon *status_icon)
-{
- g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), FALSE);
-
- return status_icon->priv->visible;
-}
-
-/**
- * gtk_status_icon_is_embedded:
- * @status_icon: a #GtkStatusIcon
- *
- * Returns whether the status icon is embedded in a notification
- * area.
- *
- * Returns: %TRUE if the status icon is embedded in
- * a notification area.
- *
- * Since: 2.10
- **/
-gboolean
-gtk_status_icon_is_embedded (GtkStatusIcon *status_icon)
-{
- g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), FALSE);
-
-#ifdef GDK_WINDOWING_X11
- if (status_icon->priv->tray_icon &&
- gtk_plug_get_embedded (GTK_PLUG (status_icon->priv->tray_icon)))
- return TRUE;
- else
- return FALSE;
-#endif
-#ifdef GDK_WINDOWING_WIN32
- return TRUE;
-#endif
-#ifdef GDK_WINDOWING_QUARTZ
- return TRUE;
-#endif
-}
-
-/**
- * gtk_status_icon_position_menu:
- * @menu: the #GtkMenu
- * @x: (out): return location for the x position
- * @y: (out): return location for the y position
- * @push_in: (out): whether the first menu item should be offset
- * (pushed in) to be aligned with the menu popup position
- * (only useful for GtkOptionMenu).
- * @user_data: (type GtkStatusIcon): the status icon to position the menu on
- *
- * Menu positioning function to use with gtk_menu_popup()
- * to position @menu aligned to the status icon @user_data.
- *
- * Since: 2.10
- **/
-void
-gtk_status_icon_position_menu (GtkMenu *menu,
- gint *x,
- gint *y,
- gboolean *push_in,
- gpointer user_data)
-{
-#ifdef GDK_WINDOWING_X11
- GtkStatusIcon *status_icon = GTK_STATUS_ICON (user_data);
- GtkStatusIconPrivate *priv = status_icon->priv;
- GtkAllocation allocation;
- GtkTrayIcon *tray_icon;
- GtkWidget *widget;
- GdkScreen *screen;
- GtkTextDirection direction;
- GtkRequisition menu_req;
- GdkRectangle monitor;
- GdkWindow *window;
- gint monitor_num, height, width, xoffset, yoffset;
-
- g_return_if_fail (GTK_IS_MENU (menu));
- g_return_if_fail (GTK_IS_STATUS_ICON (user_data));
-
- if (priv->tray_icon == NULL)
- {
- *x = 0;
- *y = 0;
- return;
- }
-
- tray_icon = GTK_TRAY_ICON (priv->tray_icon);
- widget = priv->tray_icon;
-
- direction = gtk_widget_get_direction (widget);
-
- screen = gtk_widget_get_screen (widget);
- gtk_menu_set_screen (menu, screen);
-
- window = gtk_widget_get_window (widget);
- monitor_num = gdk_screen_get_monitor_at_window (screen, window);
- if (monitor_num < 0)
- monitor_num = 0;
- gtk_menu_set_monitor (menu, monitor_num);
-
- gdk_screen_get_monitor_workarea (screen, monitor_num, &monitor);
-
- gdk_window_get_origin (window, x, y);
-
- menu_req.width = gtk_widget_get_allocated_width (GTK_WIDGET (menu));
- menu_req.height = gtk_widget_get_allocated_height (GTK_WIDGET (menu));
-
- gtk_widget_get_allocation (widget, &allocation);
- if (_gtk_tray_icon_get_orientation (tray_icon) == GTK_ORIENTATION_VERTICAL)
- {
- width = 0;
- height = allocation.height;
- xoffset = allocation.width;
- yoffset = 0;
- }
- else
- {
- width = allocation.width;
- height = 0;
- xoffset = 0;
- yoffset = allocation.height;
- }
-
- if (direction == GTK_TEXT_DIR_RTL)
- {
- if ((*x - (menu_req.width - width)) >= monitor.x)
- *x -= menu_req.width - width;
- else if ((*x + xoffset + menu_req.width) < (monitor.x + monitor.width))
- *x += xoffset;
- else if ((monitor.x + monitor.width - (*x + xoffset)) < *x)
- *x -= menu_req.width - width;
- else
- *x += xoffset;
- }
- else
- {
- if ((*x + xoffset + menu_req.width) < (monitor.x + monitor.width))
- *x += xoffset;
- else if ((*x - (menu_req.width - width)) >= monitor.x)
- *x -= menu_req.width - width;
- else if ((monitor.x + monitor.width - (*x + xoffset)) > *x)
- *x += xoffset;
- else
- *x -= menu_req.width - width;
- }
-
- if ((*y + yoffset + menu_req.height) < (monitor.y + monitor.height))
- *y += yoffset;
- else if ((*y - (menu_req.height - height)) >= monitor.y)
- *y -= menu_req.height - height;
- else if (monitor.y + monitor.height - (*y + yoffset) > *y)
- *y += yoffset;
- else
- *y -= menu_req.height - height;
-
- *push_in = FALSE;
-#endif /* GDK_WINDOWING_X11 */
-
-#ifdef GDK_WINDOWING_WIN32
- GtkStatusIcon *status_icon;
- GtkStatusIconPrivate *priv;
- GtkRequisition menu_req;
-
- g_return_if_fail (GTK_IS_MENU (menu));
- g_return_if_fail (GTK_IS_STATUS_ICON (user_data));
-
- status_icon = GTK_STATUS_ICON (user_data);
- priv = status_icon->priv;
-
- gtk_widget_get_preferred_size (GTK_WIDGET (menu), &menu_req, NULL);
-
- *x = priv->last_click_x;
- *y = priv->taskbar_top - menu_req.height;
-
- *push_in = TRUE;
-#endif
-}
-
-/**
- * gtk_status_icon_get_geometry:
- * @status_icon: a #GtkStatusIcon
- * @screen: (out) (transfer none) (allow-none): return location for
- * the screen, or %NULL if the information is not needed
- * @area: (out) (allow-none): return location for the area occupied by
- * the status icon, or %NULL
- * @orientation: (out) (allow-none): return location for the
- * orientation of the panel in which the status icon is embedded,
- * or %NULL. A panel at the top or bottom of the screen is
- * horizontal, a panel at the left or right is vertical.
- *
- * Obtains information about the location of the status icon
- * on screen. This information can be used to e.g. position
- * popups like notification bubbles.
- *
- * See gtk_status_icon_position_menu() for a more convenient
- * alternative for positioning menus.
- *
- * Note that some platforms do not allow GTK+ to provide
- * this information, and even on platforms that do allow it,
- * the information is not reliable unless the status icon
- * is embedded in a notification area, see
- * gtk_status_icon_is_embedded().
- *
- * Returns: %TRUE if the location information has
- * been filled in
- *
- * Since: 2.10
- */
-gboolean
-gtk_status_icon_get_geometry (GtkStatusIcon *status_icon,
- GdkScreen **screen,
- GdkRectangle *area,
- GtkOrientation *orientation)
-{
-#ifdef GDK_WINDOWING_X11
- GtkStatusIconPrivate *priv = status_icon->priv;
- GtkAllocation allocation;
- GtkWidget *widget;
- gint x, y;
-
- g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), FALSE);
-
- if (priv->tray_icon == NULL)
- return FALSE;
-
- widget = priv->tray_icon;
-
- if (screen)
- *screen = gtk_widget_get_screen (widget);
-
- if (area)
- {
- gdk_window_get_origin (gtk_widget_get_window (widget),
- &x, &y);
-
- gtk_widget_get_allocation (widget, &allocation);
- area->x = x;
- area->y = y;
- area->width = allocation.width;
- area->height = allocation.height;
- }
-
- if (orientation)
- *orientation = _gtk_tray_icon_get_orientation (GTK_TRAY_ICON (widget));
-
- return TRUE;
-#else
- return FALSE;
-#endif /* GDK_WINDOWING_X11 */
-}
-
-/**
- * gtk_status_icon_set_has_tooltip:
- * @status_icon: a #GtkStatusIcon
- * @has_tooltip: whether or not @status_icon has a tooltip
- *
- * Sets the has-tooltip property on @status_icon to @has_tooltip.
- * See #GtkStatusIcon:has-tooltip for more information.
- *
- * Since: 2.16
- */
-void
-gtk_status_icon_set_has_tooltip (GtkStatusIcon *status_icon,
- gboolean has_tooltip)
-{
- GtkStatusIconPrivate *priv;
- gboolean changed = FALSE;
-
- g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
-
- priv = status_icon->priv;
-
-#ifdef GDK_WINDOWING_X11
- if (priv->tray_icon)
- {
- if (gtk_widget_get_has_tooltip (priv->tray_icon) != has_tooltip)
- {
- gtk_widget_set_has_tooltip (priv->tray_icon, has_tooltip);
- changed = TRUE;
- }
- }
-#endif
-#ifdef GDK_WINDOWING_WIN32
- changed = TRUE;
- if (!has_tooltip && priv->tooltip_text)
- gtk_status_icon_set_tooltip_text (status_icon, NULL);
-#endif
-#ifdef GDK_WINDOWING_QUARTZ
- changed = TRUE;
- if (!has_tooltip && priv->tooltip_text)
- gtk_status_icon_set_tooltip_text (status_icon, NULL);
-#endif
-
- if (changed)
- g_object_notify (G_OBJECT (status_icon), "has-tooltip");
-}
-
-/**
- * gtk_status_icon_get_has_tooltip:
- * @status_icon: a #GtkStatusIcon
- *
- * Returns the current value of the has-tooltip property.
- * See #GtkStatusIcon:has-tooltip for more information.
- *
- * Returns: current value of has-tooltip on @status_icon.
- *
- * Since: 2.16
- */
-gboolean
-gtk_status_icon_get_has_tooltip (GtkStatusIcon *status_icon)
-{
- GtkStatusIconPrivate *priv;
- gboolean has_tooltip = FALSE;
-
- g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), FALSE);
-
- priv = status_icon->priv;
-
-#ifdef GDK_WINDOWING_X11
- if (priv->tray_icon)
- has_tooltip = gtk_widget_get_has_tooltip (priv->tray_icon);
-#endif
-#ifdef GDK_WINDOWING_WIN32
- has_tooltip = (priv->tooltip_text != NULL);
-#endif
-#ifdef GDK_WINDOWING_QUARTZ
- has_tooltip = (priv->tooltip_text != NULL);
-#endif
-
- return has_tooltip;
-}
-
-/**
- * gtk_status_icon_set_tooltip_text:
- * @status_icon: a #GtkStatusIcon
- * @text: the contents of the tooltip for @status_icon
- *
- * Sets @text as the contents of the tooltip.
- *
- * This function will take care of setting #GtkStatusIcon:has-tooltip to
- * %TRUE and of the default handler for the #GtkStatusIcon::query-tooltip
- * signal.
- *
- * See also the #GtkStatusIcon:tooltip-text property and
- * gtk_tooltip_set_text().
- *
- * Since: 2.16
- */
-void
-gtk_status_icon_set_tooltip_text (GtkStatusIcon *status_icon,
- const gchar *text)
-{
- GtkStatusIconPrivate *priv;
-
- g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
-
- priv = status_icon->priv;
-
-#ifdef GDK_WINDOWING_X11
- if (priv->tray_icon)
- gtk_widget_set_tooltip_text (priv->tray_icon, text);
-#endif
-#ifdef GDK_WINDOWING_WIN32
- if (text == NULL)
- priv->nid.uFlags &= ~NIF_TIP;
- else
- {
- WCHAR *wcs = g_utf8_to_utf16 (text, -1, NULL, NULL, NULL);
-
- priv->nid.uFlags |= NIF_TIP;
- wcsncpy (priv->nid.szTip, wcs, G_N_ELEMENTS (priv->nid.szTip) - 1);
- priv->nid.szTip[G_N_ELEMENTS (priv->nid.szTip) - 1] = 0;
- g_free (wcs);
- }
- if (priv->nid.hWnd != NULL && priv->visible)
- if (!Shell_NotifyIconW (NIM_MODIFY, &priv->nid))
- g_warning (G_STRLOC ": Shell_NotifyIconW(NIM_MODIFY) failed");
-
- g_free (priv->tooltip_text);
- priv->tooltip_text = g_strdup (text);
-#endif
-#ifdef GDK_WINDOWING_QUARTZ
- QUARTZ_POOL_ALLOC;
- [priv->status_item setToolTip:text];
- QUARTZ_POOL_RELEASE;
-
- g_free (priv->tooltip_text);
- priv->tooltip_text = g_strdup (text);
-#endif
-}
-
-/**
- * gtk_status_icon_get_tooltip_text:
- * @status_icon: a #GtkStatusIcon
- *
- * Gets the contents of the tooltip for @status_icon.
- *
- * Returns: the tooltip text, or %NULL. You should free the
- * returned string with g_free() when done.
- *
- * Since: 2.16
- */
-gchar *
-gtk_status_icon_get_tooltip_text (GtkStatusIcon *status_icon)
-{
- GtkStatusIconPrivate *priv;
- gchar *tooltip_text = NULL;
-
- g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
-
- priv = status_icon->priv;
-
-#ifdef GDK_WINDOWING_X11
- if (priv->tray_icon)
- tooltip_text = gtk_widget_get_tooltip_text (priv->tray_icon);
-#endif
-#ifdef GDK_WINDOWING_WIN32
- if (priv->tooltip_text)
- tooltip_text = g_strdup (priv->tooltip_text);
-#endif
-#ifdef GDK_WINDOWING_QUARTZ
- if (priv->tooltip_text)
- tooltip_text = g_strdup (priv->tooltip_text);
-#endif
-
- return tooltip_text;
-}
-
-/**
- * gtk_status_icon_set_tooltip_markup:
- * @status_icon: a #GtkStatusIcon
- * @markup: (allow-none): the contents of the tooltip for @status_icon, or %NULL
- *
- * Sets @markup as the contents of the tooltip, which is marked up with
- * the [Pango text markup language][PangoMarkupFormat].
- *
- * This function will take care of setting #GtkStatusIcon:has-tooltip to %TRUE
- * and of the default handler for the #GtkStatusIcon::query-tooltip signal.
- *
- * See also the #GtkStatusIcon:tooltip-markup property and
- * gtk_tooltip_set_markup().
- *
- * Since: 2.16
- */
-void
-gtk_status_icon_set_tooltip_markup (GtkStatusIcon *status_icon,
- const gchar *markup)
-{
-#ifdef GDK_WINDOWING_X11
- GtkStatusIconPrivate *priv;
-#else
- gchar *text = NULL;
-#endif
-
- g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
-
-#ifdef GDK_WINDOWING_X11
- priv = status_icon->priv;
-
- if (priv->tray_icon)
- gtk_widget_set_tooltip_markup (priv->tray_icon, markup);
-#endif
-#ifdef GDK_WINDOWING_WIN32
- if (markup)
- pango_parse_markup (markup, -1, 0, NULL, &text, NULL, NULL);
- gtk_status_icon_set_tooltip_text (status_icon, text);
- g_free (text);
-#endif
-#ifdef GDK_WINDOWING_QUARTZ
- if (markup)
- pango_parse_markup (markup, -1, 0, NULL, &text, NULL, NULL);
- gtk_status_icon_set_tooltip_text (status_icon, text);
- g_free (text);
-#endif
-}
-
-/**
- * gtk_status_icon_get_tooltip_markup:
- * @status_icon: a #GtkStatusIcon
- *
- * Gets the contents of the tooltip for @status_icon.
- *
- * Returns: the tooltip text, or %NULL. You should free the
- * returned string with g_free() when done.
- *
- * Since: 2.16
- */
-gchar *
-gtk_status_icon_get_tooltip_markup (GtkStatusIcon *status_icon)
-{
- GtkStatusIconPrivate *priv;
- gchar *markup = NULL;
-
- g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
-
- priv = status_icon->priv;
-
-#ifdef GDK_WINDOWING_X11
- if (priv->tray_icon)
- markup = gtk_widget_get_tooltip_markup (priv->tray_icon);
-#endif
-#ifdef GDK_WINDOWING_WIN32
- if (priv->tooltip_text)
- markup = g_markup_escape_text (priv->tooltip_text, -1);
-#endif
-#ifdef GDK_WINDOWING_QUARTZ
- if (priv->tooltip_text)
- markup = g_markup_escape_text (priv->tooltip_text, -1);
-#endif
-
- return markup;
-}
-
-/**
- * gtk_status_icon_get_x11_window_id:
- * @status_icon: a #GtkStatusIcon
- *
- * This function is only useful on the X11/freedesktop.org platform.
- * It returns a window ID for the widget in the underlying
- * status icon implementation. This is useful for the Galago
- * notification service, which can send a window ID in the protocol
- * in order for the server to position notification windows
- * pointing to a status icon reliably.
- *
- * This function is not intended for other use cases which are
- * more likely to be met by one of the non-X11 specific methods, such
- * as gtk_status_icon_position_menu().
- *
- * Returns: An 32 bit unsigned integer identifier for the
- * underlying X11 Window
- *
- * Since: 2.14
- */
-guint32
-gtk_status_icon_get_x11_window_id (GtkStatusIcon *status_icon)
-{
-#ifdef GDK_WINDOWING_X11
- if (status_icon->priv->tray_icon)
- {
- gtk_widget_realize (GTK_WIDGET (status_icon->priv->tray_icon));
- return GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (status_icon->priv->tray_icon)));
- }
- else
-#endif
- return 0;
-}
-
-/**
- * gtk_status_icon_set_title:
- * @status_icon: a #GtkStatusIcon
- * @title: the title
- *
- * Sets the title of this tray icon.
- * This should be a short, human-readable, localized string
- * describing the tray icon. It may be used by tools like screen
- * readers to render the tray icon.
- *
- * Since: 2.18
- */
-void
-gtk_status_icon_set_title (GtkStatusIcon *status_icon,
- const gchar *title)
-{
- GtkStatusIconPrivate *priv;
-
- g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
-
- priv = status_icon->priv;
-
-#ifdef GDK_WINDOWING_X11
- if (priv->tray_icon)
- gtk_window_set_title (GTK_WINDOW (priv->tray_icon), title);
-#endif
-#ifdef GDK_WINDOWING_QUARTZ
- g_free (priv->title);
- priv->title = g_strdup (title);
-#endif
-#ifdef GDK_WINDOWING_WIN32
- g_free (priv->title);
- priv->title = g_strdup (title);
-#endif
-
- g_object_notify (G_OBJECT (status_icon), "title");
-}
-
-/**
- * gtk_status_icon_get_title:
- * @status_icon: a #GtkStatusIcon
- *
- * Gets the title of this tray icon. See gtk_status_icon_set_title().
- *
- * Returns: the title of the status icon
- *
- * Since: 2.18
- */
-const gchar *
-gtk_status_icon_get_title (GtkStatusIcon *status_icon)
-{
- GtkStatusIconPrivate *priv;
- const gchar *title = NULL;
-
- g_return_val_if_fail (GTK_IS_STATUS_ICON (status_icon), NULL);
-
- priv = status_icon->priv;
-
-#ifdef GDK_WINDOWING_X11
- if (priv->tray_icon)
- title = gtk_window_get_title (GTK_WINDOW (priv->tray_icon));
-#endif
-#ifdef GDK_WINDOWING_QUARTZ
- title = priv->title;
-#endif
-#ifdef GDK_WINDOWING_WIN32
- title = priv->title;
-#endif
-
- return title;
-}
-
-
-/**
- * gtk_status_icon_set_name:
- * @status_icon: a #GtkStatusIcon
- * @name: the name
- *
- * Sets the name of this tray icon.
- * This should be a string identifying this icon. It is may be
- * used for sorting the icons in the tray and will not be shown to
- * the user.
- *
- * Since: 2.20
- */
-void
-gtk_status_icon_set_name (GtkStatusIcon *status_icon,
- const gchar *name)
-{
-#ifdef GDK_WINDOWING_X11
- GtkStatusIconPrivate *priv;
-#endif
-
- g_return_if_fail (GTK_IS_STATUS_ICON (status_icon));
-
-#ifdef GDK_WINDOWING_X11
- priv = status_icon->priv;
-
- if (priv->tray_icon)
- {
- if (gtk_widget_get_realized (priv->tray_icon))
- {
- /* gtk_window_set_wmclass() only operates on non-realized windows,
- * so temporarily unrealize the tray here
- */
- gtk_widget_hide (priv->tray_icon);
- gtk_widget_unrealize (priv->tray_icon);
- gtk_window_set_wmclass (GTK_WINDOW (priv->tray_icon), name, name);
- gtk_widget_show (priv->tray_icon);
- }
- else
- gtk_window_set_wmclass (GTK_WINDOW (priv->tray_icon), name, name);
- }
-#endif
-}
+++ /dev/null
-/* gtkstatusicon.h:
- *
- * Copyright (C) 2003 Sun Microsystems, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Mark McLoughlin <mark@skynet.ie>
- */
-
-#ifndef __GTK_STATUS_ICON_H__
-#define __GTK_STATUS_ICON_H__
-
-#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
-#error "Only <gtk/gtk.h> can be included directly."
-#endif
-
-#include <gtk/gtkimage.h>
-#include <gtk/gtkmenu.h>
-
-G_BEGIN_DECLS
-
-#define GTK_TYPE_STATUS_ICON (gtk_status_icon_get_type ())
-#define GTK_STATUS_ICON(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_STATUS_ICON, GtkStatusIcon))
-#define GTK_STATUS_ICON_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GTK_TYPE_STATUS_ICON, GtkStatusIconClass))
-#define GTK_IS_STATUS_ICON(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_STATUS_ICON))
-#define GTK_IS_STATUS_ICON_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GTK_TYPE_STATUS_ICON))
-#define GTK_STATUS_ICON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_STATUS_ICON, GtkStatusIconClass))
-
-typedef struct _GtkStatusIcon GtkStatusIcon;
-typedef struct _GtkStatusIconClass GtkStatusIconClass;
-typedef struct _GtkStatusIconPrivate GtkStatusIconPrivate;
-
-struct _GtkStatusIcon
-{
- GObject parent_instance;
-
- GtkStatusIconPrivate *priv;
-};
-
-struct _GtkStatusIconClass
-{
- GObjectClass parent_class;
-
- void (* activate) (GtkStatusIcon *status_icon);
- void (* popup_menu) (GtkStatusIcon *status_icon,
- guint button,
- guint32 activate_time);
- gboolean (* size_changed) (GtkStatusIcon *status_icon,
- gint size);
- gboolean (* button_press_event) (GtkStatusIcon *status_icon,
- GdkEventButton *event);
- gboolean (* button_release_event) (GtkStatusIcon *status_icon,
- GdkEventButton *event);
- gboolean (* scroll_event) (GtkStatusIcon *status_icon,
- GdkEventScroll *event);
- gboolean (* query_tooltip) (GtkStatusIcon *status_icon,
- gint x,
- gint y,
- gboolean keyboard_mode,
- GtkTooltip *tooltip);
-
- void (*__gtk_reserved1);
- void (*__gtk_reserved2);
- void (*__gtk_reserved3);
- void (*__gtk_reserved4);
-};
-
-GDK_AVAILABLE_IN_ALL
-GType gtk_status_icon_get_type (void) G_GNUC_CONST;
-
-GDK_AVAILABLE_IN_ALL
-GtkStatusIcon *gtk_status_icon_new (void);
-GDK_AVAILABLE_IN_ALL
-GtkStatusIcon *gtk_status_icon_new_from_pixbuf (GdkPixbuf *pixbuf);
-GDK_AVAILABLE_IN_ALL
-GtkStatusIcon *gtk_status_icon_new_from_file (const gchar *filename);
-GDK_DEPRECATED_IN_3_10_FOR(gtk_status_icon_new_from_icon_name)
-GtkStatusIcon *gtk_status_icon_new_from_stock (const gchar *stock_id);
-GDK_AVAILABLE_IN_ALL
-GtkStatusIcon *gtk_status_icon_new_from_icon_name (const gchar *icon_name);
-GDK_AVAILABLE_IN_ALL
-GtkStatusIcon *gtk_status_icon_new_from_gicon (GIcon *icon);
-
-GDK_AVAILABLE_IN_ALL
-void gtk_status_icon_set_from_pixbuf (GtkStatusIcon *status_icon,
- GdkPixbuf *pixbuf);
-GDK_AVAILABLE_IN_ALL
-void gtk_status_icon_set_from_file (GtkStatusIcon *status_icon,
- const gchar *filename);
-GDK_DEPRECATED_IN_3_10_FOR(gtk_status_icon_set_from_icon_name)
-void gtk_status_icon_set_from_stock (GtkStatusIcon *status_icon,
- const gchar *stock_id);
-GDK_AVAILABLE_IN_ALL
-void gtk_status_icon_set_from_icon_name (GtkStatusIcon *status_icon,
- const gchar *icon_name);
-GDK_AVAILABLE_IN_ALL
-void gtk_status_icon_set_from_gicon (GtkStatusIcon *status_icon,
- GIcon *icon);
-
-GDK_AVAILABLE_IN_ALL
-GtkImageType gtk_status_icon_get_storage_type (GtkStatusIcon *status_icon);
-
-GDK_AVAILABLE_IN_ALL
-GdkPixbuf *gtk_status_icon_get_pixbuf (GtkStatusIcon *status_icon);
-GDK_DEPRECATED_IN_3_10_FOR(gtk_status_icon_get_icon_name)
-const gchar * gtk_status_icon_get_stock (GtkStatusIcon *status_icon);
-GDK_AVAILABLE_IN_ALL
-const gchar * gtk_status_icon_get_icon_name (GtkStatusIcon *status_icon);
-GDK_AVAILABLE_IN_ALL
-GIcon *gtk_status_icon_get_gicon (GtkStatusIcon *status_icon);
-
-GDK_AVAILABLE_IN_ALL
-gint gtk_status_icon_get_size (GtkStatusIcon *status_icon);
-
-GDK_AVAILABLE_IN_ALL
-void gtk_status_icon_set_screen (GtkStatusIcon *status_icon,
- GdkScreen *screen);
-GDK_AVAILABLE_IN_ALL
-GdkScreen *gtk_status_icon_get_screen (GtkStatusIcon *status_icon);
-
-GDK_AVAILABLE_IN_ALL
-void gtk_status_icon_set_has_tooltip (GtkStatusIcon *status_icon,
- gboolean has_tooltip);
-GDK_AVAILABLE_IN_ALL
-void gtk_status_icon_set_tooltip_text (GtkStatusIcon *status_icon,
- const gchar *text);
-GDK_AVAILABLE_IN_ALL
-void gtk_status_icon_set_tooltip_markup (GtkStatusIcon *status_icon,
- const gchar *markup);
-GDK_AVAILABLE_IN_ALL
-void gtk_status_icon_set_title (GtkStatusIcon *status_icon,
- const gchar *title);
-GDK_AVAILABLE_IN_ALL
-const gchar * gtk_status_icon_get_title (GtkStatusIcon *status_icon);
-GDK_AVAILABLE_IN_ALL
-void gtk_status_icon_set_name (GtkStatusIcon *status_icon,
- const gchar *name);
-GDK_AVAILABLE_IN_ALL
-void gtk_status_icon_set_visible (GtkStatusIcon *status_icon,
- gboolean visible);
-GDK_AVAILABLE_IN_ALL
-gboolean gtk_status_icon_get_visible (GtkStatusIcon *status_icon);
-
-GDK_AVAILABLE_IN_ALL
-gboolean gtk_status_icon_is_embedded (GtkStatusIcon *status_icon);
-
-GDK_AVAILABLE_IN_ALL
-void gtk_status_icon_position_menu (GtkMenu *menu,
- gint *x,
- gint *y,
- gboolean *push_in,
- gpointer user_data);
-GDK_AVAILABLE_IN_ALL
-gboolean gtk_status_icon_get_geometry (GtkStatusIcon *status_icon,
- GdkScreen **screen,
- GdkRectangle *area,
- GtkOrientation *orientation);
-GDK_AVAILABLE_IN_ALL
-gboolean gtk_status_icon_get_has_tooltip (GtkStatusIcon *status_icon);
-GDK_AVAILABLE_IN_ALL
-gchar *gtk_status_icon_get_tooltip_text (GtkStatusIcon *status_icon);
-GDK_AVAILABLE_IN_ALL
-gchar *gtk_status_icon_get_tooltip_markup (GtkStatusIcon *status_icon);
-
-GDK_AVAILABLE_IN_ALL
-guint32 gtk_status_icon_get_x11_window_id (GtkStatusIcon *status_icon);
-
-G_END_DECLS
-
-#endif /* __GTK_STATUS_ICON_H__ */
+++ /dev/null
-/* gtktrayicon.c
- * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * This is an implementation of the freedesktop.org “system tray” spec,
- * http://www.freedesktop.org/wiki/Standards/systemtray-spec
- */
-
-#include "config.h"
-
-#include <math.h>
-#include <string.h>
-
-#include "x11/gdkx.h"
-#include <X11/Xatom.h>
-#include <cairo-xlib.h>
-
-#include "gtkintl.h"
-#include "gtkprivate.h"
-#include "gtktrayicon.h"
-#include "gtktestutils.h"
-#include "gtkdebug.h"
-#include "gtktypebuiltins.h"
-
-#define SYSTEM_TRAY_REQUEST_DOCK 0
-#define SYSTEM_TRAY_BEGIN_MESSAGE 1
-#define SYSTEM_TRAY_CANCEL_MESSAGE 2
-
-#define SYSTEM_TRAY_ORIENTATION_HORZ 0
-#define SYSTEM_TRAY_ORIENTATION_VERT 1
-
-enum {
- PROP_0,
- PROP_ORIENTATION,
- PROP_FG_COLOR,
- PROP_ERROR_COLOR,
- PROP_WARNING_COLOR,
- PROP_SUCCESS_COLOR,
- PROP_PADDING,
- PROP_ICON_SIZE
-};
-
-struct _GtkTrayIconPrivate
-{
- guint stamp;
-
- Atom selection_atom;
- Atom manager_atom;
- Atom system_tray_opcode_atom;
- Atom orientation_atom;
- Atom visual_atom;
- Atom colors_atom;
- Atom padding_atom;
- Atom icon_size_atom;
- Window manager_window;
- GdkVisual *manager_visual;
- gboolean manager_visual_rgba;
-
- GtkOrientation orientation;
- GdkRGBA fg_color;
- GdkRGBA error_color;
- GdkRGBA warning_color;
- GdkRGBA success_color;
- gint padding;
- gint icon_size;
-};
-
-static void gtk_tray_icon_constructed (GObject *object);
-static void gtk_tray_icon_dispose (GObject *object);
-
-static void gtk_tray_icon_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-
-static void gtk_tray_icon_realize (GtkWidget *widget);
-static void gtk_tray_icon_style_updated (GtkWidget *widget);
-static gboolean gtk_tray_icon_delete (GtkWidget *widget,
- GdkEventAny *event);
-static gboolean gtk_tray_icon_draw (GtkWidget *widget,
- cairo_t *cr);
-
-static void gtk_tray_icon_clear_manager_window (GtkTrayIcon *icon);
-static void gtk_tray_icon_update_manager_window (GtkTrayIcon *icon);
-static void gtk_tray_icon_manager_window_destroyed (GtkTrayIcon *icon);
-
-static GdkFilterReturn gtk_tray_icon_manager_filter (GdkXEvent *xevent,
- GdkEvent *event,
- gpointer user_data);
-
-
-G_DEFINE_TYPE_WITH_PRIVATE (GtkTrayIcon, gtk_tray_icon, GTK_TYPE_PLUG)
-
-static void
-gtk_tray_icon_class_init (GtkTrayIconClass *class)
-{
- GObjectClass *gobject_class = (GObjectClass *)class;
- GtkWidgetClass *widget_class = (GtkWidgetClass *)class;
-
- gobject_class->get_property = gtk_tray_icon_get_property;
- gobject_class->constructed = gtk_tray_icon_constructed;
- gobject_class->dispose = gtk_tray_icon_dispose;
-
- widget_class->realize = gtk_tray_icon_realize;
- widget_class->style_updated = gtk_tray_icon_style_updated;
- widget_class->delete_event = gtk_tray_icon_delete;
- widget_class->draw = gtk_tray_icon_draw;
-
- g_object_class_install_property (gobject_class,
- PROP_ORIENTATION,
- g_param_spec_enum ("orientation",
- P_("Orientation"),
- P_("The orientation of the tray"),
- GTK_TYPE_ORIENTATION,
- GTK_ORIENTATION_HORIZONTAL,
- GTK_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_FG_COLOR,
- g_param_spec_boxed ("fg-color",
- P_("Foreground color"),
- P_("Foreground color for symbolic icons"),
- GDK_TYPE_RGBA,
- GTK_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_ERROR_COLOR,
- g_param_spec_boxed ("error-color",
- P_("Error color"),
- P_("Error color for symbolic icons"),
- GDK_TYPE_RGBA,
- GTK_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_WARNING_COLOR,
- g_param_spec_boxed ("warning-color",
- P_("Warning color"),
- P_("Warning color for symbolic icons"),
- GDK_TYPE_RGBA,
- GTK_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_SUCCESS_COLOR,
- g_param_spec_boxed ("success-color",
- P_("Success color"),
- P_("Success color for symbolic icons"),
- GDK_TYPE_RGBA,
- GTK_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_PADDING,
- g_param_spec_int ("padding",
- P_("Padding"),
- P_("Padding that should be put around icons in the tray"),
- 0,
- G_MAXINT,
- 0,
- GTK_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_ICON_SIZE,
- g_param_spec_int ("icon-size",
- P_("Icon Size"),
- P_("The pixel size that icons should be forced to, or zero"),
- 0,
- G_MAXINT,
- 0,
- GTK_PARAM_READABLE));
-}
-
-static void
-gtk_tray_icon_init (GtkTrayIcon *icon)
-{
- icon->priv = gtk_tray_icon_get_instance_private (icon);
- icon->priv->stamp = 1;
- icon->priv->orientation = GTK_ORIENTATION_HORIZONTAL;
- icon->priv->fg_color.red = 0.0;
- icon->priv->fg_color.green = 0.0;
- icon->priv->fg_color.blue = 0.0;
- icon->priv->fg_color.alpha = 1.0;
- icon->priv->error_color.red = 0.7968;
- icon->priv->error_color.green = 0.0;
- icon->priv->error_color.blue = 0.0;
- icon->priv->error_color.alpha = 1.0;
- icon->priv->warning_color.red = 0.9570;
- icon->priv->warning_color.green = 0.4726;
- icon->priv->warning_color.blue = 0.2421;
- icon->priv->warning_color.alpha = 1.0;
- icon->priv->success_color.red = 0.3047;
- icon->priv->success_color.green = 0.6016;
- icon->priv->success_color.blue = 0.0234;
- icon->priv->success_color.alpha = 1.0;
- icon->priv->padding = 0;
- icon->priv->icon_size = 0;
-
- gtk_widget_set_app_paintable (GTK_WIDGET (icon), TRUE);
- gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK);
-}
-
-static void
-gtk_tray_icon_constructed (GObject *object)
-{
- /* Do setup that depends on the screen; screen has been set at this point */
-
- GtkTrayIcon *icon = GTK_TRAY_ICON (object);
- GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (object));
- GdkWindow *root_window = gdk_screen_get_root_window (screen);
- GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (object));
- Display *xdisplay = gdk_x11_display_get_xdisplay (display);
- char buffer[256];
-
- g_snprintf (buffer, sizeof (buffer),
- "_NET_SYSTEM_TRAY_S%d",
- gdk_screen_get_number (screen));
-
- icon->priv->selection_atom = XInternAtom (xdisplay, buffer, False);
-
- icon->priv->manager_atom = XInternAtom (xdisplay, "MANAGER", False);
-
- icon->priv->system_tray_opcode_atom = XInternAtom (xdisplay,
- "_NET_SYSTEM_TRAY_OPCODE",
- False);
-
- icon->priv->orientation_atom = XInternAtom (xdisplay,
- "_NET_SYSTEM_TRAY_ORIENTATION",
- False);
-
- icon->priv->visual_atom = XInternAtom (xdisplay,
- "_NET_SYSTEM_TRAY_VISUAL",
- False);
-
- icon->priv->colors_atom = XInternAtom (xdisplay,
- "_NET_SYSTEM_TRAY_COLORS",
- False);
-
- icon->priv->padding_atom = XInternAtom (xdisplay,
- "_NET_SYSTEM_TRAY_PADDING",
- False);
-
- icon->priv->icon_size_atom = XInternAtom (xdisplay,
- "_NET_SYSTEM_TRAY_ICON_SIZE",
- False);
-
- /* Add a root window filter so that we get changes on MANAGER */
- gdk_window_add_filter (root_window,
- gtk_tray_icon_manager_filter, icon);
-
- gtk_tray_icon_update_manager_window (icon);
-}
-
-static void
-gtk_tray_icon_clear_manager_window (GtkTrayIcon *icon)
-{
- GdkDisplay *display = gtk_widget_get_display (GTK_WIDGET (icon));
-
- if (icon->priv->manager_window != None)
- {
- GdkWindow *gdkwin;
-
- gdkwin = gdk_x11_window_lookup_for_display (display,
- icon->priv->manager_window);
-
- gdk_window_remove_filter (gdkwin, gtk_tray_icon_manager_filter, icon);
-
- icon->priv->manager_window = None;
- icon->priv->manager_visual = NULL;
- }
-}
-
-static void
-gtk_tray_icon_dispose (GObject *object)
-{
- GtkTrayIcon *icon = GTK_TRAY_ICON (object);
- GtkWidget *widget = GTK_WIDGET (object);
- GdkWindow *root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget));
-
- gtk_tray_icon_clear_manager_window (icon);
-
- gdk_window_remove_filter (root_window, gtk_tray_icon_manager_filter, icon);
-
- G_OBJECT_CLASS (gtk_tray_icon_parent_class)->dispose (object);
-}
-
-static void
-gtk_tray_icon_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GtkTrayIcon *icon = GTK_TRAY_ICON (object);
-
- switch (prop_id)
- {
- case PROP_ORIENTATION:
- g_value_set_enum (value, icon->priv->orientation);
- break;
- case PROP_FG_COLOR:
- g_value_set_boxed (value, &icon->priv->fg_color);
- break;
- case PROP_ERROR_COLOR:
- g_value_set_boxed (value, &icon->priv->error_color);
- break;
- case PROP_WARNING_COLOR:
- g_value_set_boxed (value, &icon->priv->warning_color);
- break;
- case PROP_SUCCESS_COLOR:
- g_value_set_boxed (value, &icon->priv->success_color);
- break;
- case PROP_PADDING:
- g_value_set_int (value, icon->priv->padding);
- break;
- case PROP_ICON_SIZE:
- g_value_set_int (value, icon->priv->icon_size);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static gboolean
-gtk_tray_icon_draw (GtkWidget *widget,
- cairo_t *cr)
-{
- GtkTrayIcon *icon = GTK_TRAY_ICON (widget);
- GtkWidget *focus_child;
- GdkWindow *window;
- gint border_width;
- gboolean retval = FALSE;
- cairo_surface_t *target;
-
- window = gtk_widget_get_window (widget);
- target = cairo_get_group_target (cr);
-
- if (icon->priv->manager_visual_rgba ||
- cairo_surface_get_type (target) != CAIRO_SURFACE_TYPE_XLIB ||
- cairo_xlib_surface_get_drawable (target) != GDK_WINDOW_XID (window))
- {
- /* Clear to transparent */
- cairo_set_source_rgba (cr, 0, 0, 0, 0);
- cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
- cairo_paint (cr);
- }
-
- if (GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->draw)
- retval = GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->draw (widget, cr);
-
- focus_child = gtk_container_get_focus_child (GTK_CONTAINER (widget));
- if (focus_child && gtk_widget_has_visible_focus (focus_child))
- {
- GtkStyleContext *context;
-
- border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
- context = gtk_widget_get_style_context (widget);
-
- gtk_render_focus (context, cr, border_width, border_width,
- gtk_widget_get_allocated_width (widget) - 2 * border_width,
- gtk_widget_get_allocated_height (widget) - 2 * border_width);
- }
-
- return retval;
-}
-
-static void
-gtk_tray_icon_get_orientation_property (GtkTrayIcon *icon)
-{
- GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (icon));
- GdkDisplay *display = gdk_screen_get_display (screen);
- Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
-
- Atom type;
- int format;
- union {
- gulong *prop;
- guchar *prop_ch;
- } prop = { NULL };
- gulong nitems;
- gulong bytes_after;
- int error, result;
-
- g_assert (icon->priv->manager_window != None);
-
- gdk_error_trap_push ();
- type = None;
- result = XGetWindowProperty (xdisplay,
- icon->priv->manager_window,
- icon->priv->orientation_atom,
- 0, G_MAXLONG, FALSE,
- XA_CARDINAL,
- &type, &format, &nitems,
- &bytes_after, &(prop.prop_ch));
- error = gdk_error_trap_pop ();
-
- if (error || result != Success)
- return;
-
- if (type == XA_CARDINAL && nitems == 1 && format == 32)
- {
- GtkOrientation orientation;
-
- orientation = (prop.prop [0] == SYSTEM_TRAY_ORIENTATION_HORZ) ?
- GTK_ORIENTATION_HORIZONTAL :
- GTK_ORIENTATION_VERTICAL;
-
- if (icon->priv->orientation != orientation)
- {
- icon->priv->orientation = orientation;
-
- g_object_notify (G_OBJECT (icon), "orientation");
- }
- }
-
- if (type != None)
- XFree (prop.prop);
-}
-
-static void
-gtk_tray_icon_get_visual_property (GtkTrayIcon *icon)
-{
- GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (icon));
- GdkDisplay *display = gdk_screen_get_display (screen);
- Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
-
- Atom type;
- int format;
- union {
- gulong *prop;
- guchar *prop_ch;
- } prop = { NULL };
- gulong nitems;
- gulong bytes_after;
- int error, result;
-
- g_assert (icon->priv->manager_window != None);
-
- gdk_error_trap_push ();
- type = None;
- result = XGetWindowProperty (xdisplay,
- icon->priv->manager_window,
- icon->priv->visual_atom,
- 0, G_MAXLONG, FALSE,
- XA_VISUALID,
- &type, &format, &nitems,
- &bytes_after, &(prop.prop_ch));
- error = gdk_error_trap_pop ();
-
- if (!error && result == Success &&
- type == XA_VISUALID && nitems == 1 && format == 32)
- {
- VisualID visual_id;
- GdkVisual *visual;
- gint red_prec, green_prec, blue_prec;
-
- visual_id = prop.prop[0];
- visual = gdk_x11_screen_lookup_visual (screen, visual_id);
- gdk_visual_get_red_pixel_details (visual, NULL, NULL, &red_prec);
- gdk_visual_get_green_pixel_details (visual, NULL, NULL, &green_prec);
- gdk_visual_get_blue_pixel_details (visual, NULL, NULL, &blue_prec);
- icon->priv->manager_visual = visual;
- icon->priv->manager_visual_rgba =
- (red_prec + blue_prec + green_prec < gdk_visual_get_depth (visual));
- }
- else
- {
- icon->priv->manager_visual = NULL;
- icon->priv->manager_visual_rgba = FALSE;
- }
-
- if (type != None)
- XFree (prop.prop);
-}
-
-static void
-gtk_tray_icon_get_colors_property (GtkTrayIcon *icon)
-{
- GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (icon));
- GdkDisplay *display = gdk_screen_get_display (screen);
- Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
-
- Atom type;
- int format;
- union {
- gulong *prop;
- guchar *prop_ch;
- } prop = { NULL };
- gulong nitems;
- gulong bytes_after;
- int error, result;
-
- g_assert (icon->priv->manager_window != None);
-
- gdk_error_trap_push ();
- type = None;
- result = XGetWindowProperty (xdisplay,
- icon->priv->manager_window,
- icon->priv->colors_atom,
- 0, G_MAXLONG, FALSE,
- XA_CARDINAL,
- &type, &format, &nitems,
- &bytes_after, &(prop.prop_ch));
- error = gdk_error_trap_pop ();
-
- if (error || result != Success)
- return;
-
- if (type == XA_CARDINAL && nitems == 12 && format == 32)
- {
- GdkRGBA color;
-
- g_object_freeze_notify (G_OBJECT (icon));
-
- color.red = prop.prop[0] / 65535.0;
- color.green = prop.prop[1] / 65535.0;
- color.blue = prop.prop[2] / 65535.0;
-
- if (!gdk_rgba_equal (&icon->priv->fg_color, &color))
- {
- icon->priv->fg_color = color;
-
- g_object_notify (G_OBJECT (icon), "fg-color");
- }
-
- color.red = prop.prop[3] / 65535.0;
- color.green = prop.prop[4] / 65535.0;
- color.blue = prop.prop[5] / 65535.0;
-
- if (!gdk_rgba_equal (&icon->priv->error_color, &color))
- {
- icon->priv->error_color = color;
-
- g_object_notify (G_OBJECT (icon), "error-color");
- }
-
- color.red = prop.prop[6] / 65535.0;
- color.green = prop.prop[7] / 65535.0;
- color.blue = prop.prop[8] / 65535.0;
-
- if (!gdk_rgba_equal (&icon->priv->warning_color, &color))
- {
- icon->priv->warning_color = color;
-
- g_object_notify (G_OBJECT (icon), "warning-color");
- }
-
- color.red = prop.prop[9] / 65535.0;
- color.green = prop.prop[10] / 65535.0;
- color.blue = prop.prop[11] / 65535.0;
-
- if (!gdk_rgba_equal (&icon->priv->success_color, &color))
- {
- icon->priv->success_color = color;
-
- g_object_notify (G_OBJECT (icon), "success-color");
- }
-
- g_object_thaw_notify (G_OBJECT (icon));
- }
-
- if (type != None)
- XFree (prop.prop);
-}
-
-static void
-gtk_tray_icon_get_padding_property (GtkTrayIcon *icon)
-{
- GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (icon));
- GdkDisplay *display = gdk_screen_get_display (screen);
- Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
-
- Atom type;
- int format;
- union {
- gulong *prop;
- guchar *prop_ch;
- } prop = { NULL };
- gulong nitems;
- gulong bytes_after;
- int error, result;
-
- g_assert (icon->priv->manager_window != None);
-
- gdk_error_trap_push ();
- type = None;
- result = XGetWindowProperty (xdisplay,
- icon->priv->manager_window,
- icon->priv->padding_atom,
- 0, G_MAXLONG, FALSE,
- XA_CARDINAL,
- &type, &format, &nitems,
- &bytes_after, &(prop.prop_ch));
- error = gdk_error_trap_pop ();
-
- if (!error && result == Success &&
- type == XA_CARDINAL && nitems == 1 && format == 32)
- {
- gint padding;
-
- padding = prop.prop[0];
-
- if (icon->priv->padding != padding)
- {
- icon->priv->padding = padding;
-
- g_object_notify (G_OBJECT (icon), "padding");
- }
- }
-
- if (type != None)
- XFree (prop.prop);
-}
-
-static void
-gtk_tray_icon_get_icon_size_property (GtkTrayIcon *icon)
-{
- GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (icon));
- GdkDisplay *display = gdk_screen_get_display (screen);
- Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
-
- Atom type;
- int format;
- union {
- gulong *prop;
- guchar *prop_ch;
- } prop = { NULL };
- gulong nitems;
- gulong bytes_after;
- int error, result;
-
- g_assert (icon->priv->manager_window != None);
-
- gdk_error_trap_push ();
- type = None;
- result = XGetWindowProperty (xdisplay,
- icon->priv->manager_window,
- icon->priv->icon_size_atom,
- 0, G_MAXLONG, FALSE,
- XA_CARDINAL,
- &type, &format, &nitems,
- &bytes_after, &(prop.prop_ch));
- error = gdk_error_trap_pop ();
-
- if (!error && result == Success &&
- type == XA_CARDINAL && nitems == 1 && format == 32)
- {
- gint icon_size;
-
- icon_size = prop.prop[0];
-
- if (icon->priv->icon_size != icon_size)
- {
- icon->priv->icon_size = icon_size;
-
- g_object_notify (G_OBJECT (icon), "icon-size");
- }
- }
-
- if (type != None)
- XFree (prop.prop);
-}
-
-static GdkFilterReturn
-gtk_tray_icon_manager_filter (GdkXEvent *xevent,
- GdkEvent *event,
- gpointer user_data)
-{
- GtkTrayIcon *icon = user_data;
- XEvent *xev = (XEvent *)xevent;
-
- if (xev->xany.type == ClientMessage &&
- xev->xclient.message_type == icon->priv->manager_atom &&
- xev->xclient.data.l[1] == icon->priv->selection_atom)
- {
- GTK_NOTE (PLUGSOCKET,
- g_print ("GtkStatusIcon %p: tray manager appeared\n", icon));
-
- gtk_tray_icon_update_manager_window (icon);
- }
- else if (xev->xany.window == icon->priv->manager_window)
- {
- if (xev->xany.type == PropertyNotify &&
- xev->xproperty.atom == icon->priv->orientation_atom)
- {
- GTK_NOTE (PLUGSOCKET,
- g_print ("GtkStatusIcon %p: got PropertyNotify on manager window for orientation atom\n", icon));
-
- gtk_tray_icon_get_orientation_property (icon);
- }
- else if (xev->xany.type == PropertyNotify &&
- xev->xproperty.atom == icon->priv->colors_atom)
- {
- GTK_NOTE (PLUGSOCKET,
- g_print ("GtkStatusIcon %p: got PropertyNotify on manager window for colors atom\n", icon));
-
- gtk_tray_icon_get_colors_property (icon);
- }
- else if (xev->xany.type == PropertyNotify &&
- xev->xproperty.atom == icon->priv->padding_atom)
- {
- gtk_tray_icon_get_padding_property (icon);
- }
- else if (xev->xany.type == PropertyNotify &&
- xev->xproperty.atom == icon->priv->icon_size_atom)
- {
- gtk_tray_icon_get_icon_size_property (icon);
- }
- else if (xev->xany.type == DestroyNotify)
- {
- GTK_NOTE (PLUGSOCKET,
- g_print ("GtkStatusIcon %p: got DestroyNotify for manager window\n", icon));
-
- gtk_tray_icon_manager_window_destroyed (icon);
- }
- else
- {
- GTK_NOTE (PLUGSOCKET,
- g_print ("GtkStatusIcon %p: got other message on manager window\n", icon));
- }
- }
-
- return GDK_FILTER_CONTINUE;
-}
-
-static void
-gtk_tray_icon_send_manager_message (GtkTrayIcon *icon,
- long message,
- Window window,
- long data1,
- long data2,
- long data3)
-{
- GtkWidget *widget;
- XClientMessageEvent ev;
- Display *display;
-
- widget = GTK_WIDGET (icon);
-
- memset (&ev, 0, sizeof (ev));
- ev.type = ClientMessage;
- ev.window = window;
- ev.message_type = icon->priv->system_tray_opcode_atom;
- ev.format = 32;
- ev.data.l[0] = gdk_x11_get_server_time (gtk_widget_get_window (widget));
- ev.data.l[1] = message;
- ev.data.l[2] = data1;
- ev.data.l[3] = data2;
- ev.data.l[4] = data3;
-
- display = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget));
-
- gdk_error_trap_push ();
- XSendEvent (display,
- icon->priv->manager_window, False, NoEventMask, (XEvent *)&ev);
- gdk_error_trap_pop_ignored ();
-}
-
-static void
-gtk_tray_icon_send_dock_request (GtkTrayIcon *icon)
-{
- GTK_NOTE (PLUGSOCKET,
- g_print ("GtkStatusIcon %p: sending dock request to manager window %lx\n",
- icon, (gulong) icon->priv->manager_window));
-
- gtk_tray_icon_send_manager_message (icon,
- SYSTEM_TRAY_REQUEST_DOCK,
- icon->priv->manager_window,
- gtk_plug_get_id (GTK_PLUG (icon)),
- 0, 0);
-}
-
-static void
-gtk_tray_icon_update_manager_window (GtkTrayIcon *icon)
-{
- GtkWidget *widget = GTK_WIDGET (icon);
- GdkScreen *screen = gtk_widget_get_screen (widget);
- GdkDisplay *display = gdk_screen_get_display (screen);
- Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
-
- GTK_NOTE (PLUGSOCKET,
- g_print ("GtkStatusIcon %p: updating tray icon manager window, current manager window: %lx\n",
- icon, (gulong) icon->priv->manager_window));
-
- if (icon->priv->manager_window != None)
- return;
-
- GTK_NOTE (PLUGSOCKET,
- g_print ("GtkStatusIcon %p: trying to find manager window\n", icon));
-
- XGrabServer (xdisplay);
-
- icon->priv->manager_window = XGetSelectionOwner (xdisplay,
- icon->priv->selection_atom);
-
- if (icon->priv->manager_window != None)
- XSelectInput (xdisplay,
- icon->priv->manager_window, StructureNotifyMask|PropertyChangeMask);
-
- XUngrabServer (xdisplay);
- XFlush (xdisplay);
-
- if (icon->priv->manager_window != None)
- {
- GdkWindow *gdkwin;
-
- GTK_NOTE (PLUGSOCKET,
- g_print ("GtkStatusIcon %p: is being managed by window %lx\n",
- icon, (gulong) icon->priv->manager_window));
-
- gdkwin = gdk_x11_window_lookup_for_display (display,
- icon->priv->manager_window);
-
- gdk_window_add_filter (gdkwin, gtk_tray_icon_manager_filter, icon);
-
- gtk_tray_icon_get_orientation_property (icon);
- gtk_tray_icon_get_visual_property (icon);
- gtk_tray_icon_get_colors_property (icon);
- gtk_tray_icon_get_padding_property (icon);
- gtk_tray_icon_get_icon_size_property (icon);
-
- if (gtk_widget_get_realized (GTK_WIDGET (icon)))
- {
- if ((icon->priv->manager_visual == NULL &&
- gtk_widget_get_visual (widget) == gdk_screen_get_system_visual (screen)) ||
- (icon->priv->manager_visual == gtk_widget_get_visual (widget)))
- {
- /* Already have the right visual, can just dock
- */
- gtk_tray_icon_send_dock_request (icon);
- }
- else
- {
- /* Need to re-realize the widget to get the right visual
- */
- gtk_widget_hide (widget);
- gtk_widget_unrealize (widget);
- gtk_widget_show (widget);
- }
- }
- }
- else
- {
- GTK_NOTE (PLUGSOCKET,
- g_print ("GtkStatusIcon %p: no tray manager found\n", icon));
- }
-}
-
-static void
-gtk_tray_icon_manager_window_destroyed (GtkTrayIcon *icon)
-{
- g_return_if_fail (icon->priv->manager_window != None);
-
- GTK_NOTE (PLUGSOCKET,
- g_print ("GtkStatusIcon %p: tray manager window destroyed\n", icon));
-
- gtk_tray_icon_clear_manager_window (icon);
-}
-
-static gboolean
-gtk_tray_icon_delete (GtkWidget *widget,
- GdkEventAny *event)
-{
-#ifdef G_ENABLE_DEBUG
- GtkTrayIcon *icon = GTK_TRAY_ICON (widget);
-#endif
-
- GTK_NOTE (PLUGSOCKET,
- g_print ("GtkStatusIcon %p: delete notify, tray manager window %lx\n",
- icon, (gulong) icon->priv->manager_window));
-
- /* A bug in X server versions up to x.org 1.5.0 means that:
- * XFixesChangeSaveSet(...., SaveSetRoot, SaveSetUnmap) doesn't work properly
- * and we'll left mapped in a separate toplevel window if the tray is destroyed.
- * For simplicity just get rid of our X window and start over.
- */
- gtk_widget_hide (widget);
- gtk_widget_unrealize (widget);
- gtk_widget_show (widget);
-
- /* Handled it, don't destroy the tray icon */
- return TRUE;
-}
-
-static void
-gtk_tray_icon_set_visual (GtkTrayIcon *icon)
-{
- GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (icon));
- GdkVisual *visual = icon->priv->manager_visual;
-
- /* To avoid uncertainty about colormaps, _NET_SYSTEM_TRAY_VISUAL is supposed
- * to be either the screen default visual or a TrueColor visual; ignore it
- * if it is something else
- */
- if (visual && gdk_visual_get_visual_type (visual) != GDK_VISUAL_TRUE_COLOR)
- visual = NULL;
-
- if (visual == NULL)
- visual = gdk_screen_get_system_visual (screen);
-
- gtk_widget_set_visual (GTK_WIDGET (icon), visual);
-}
-
-static void
-gtk_tray_icon_realize (GtkWidget *widget)
-{
- GtkTrayIcon *icon = GTK_TRAY_ICON (widget);
- GdkWindow *window;
-
- /* Set our visual before realizing */
- gtk_tray_icon_set_visual (icon);
-
- GTK_WIDGET_CLASS (gtk_tray_icon_parent_class)->realize (widget);
- window = gtk_widget_get_window (widget);
- if (icon->priv->manager_visual_rgba)
- {
- /* Set a transparent background */
- GdkRGBA transparent = { 0.0, 0.0, 0.0, 0.0 };
- gdk_window_set_background_rgba (window, &transparent);
- }
- else
- {
- /* Set a parent-relative background pixmap */
- gdk_window_set_background_pattern (window, NULL);
- }
-
- GTK_NOTE (PLUGSOCKET,
- g_print ("GtkStatusIcon %p: realized, window: %lx, socket window: %lx\n",
- widget,
- (gulong) GDK_WINDOW_XID (window),
- gtk_plug_get_socket_window (GTK_PLUG (icon)) ?
- (gulong) GDK_WINDOW_XID (gtk_plug_get_socket_window (GTK_PLUG (icon))) : 0UL));
-
- if (icon->priv->manager_window != None)
- gtk_tray_icon_send_dock_request (icon);
-}
-
-static void
-gtk_tray_icon_style_updated (GtkWidget *widget)
-{
- /* The default handler resets the background according to the style. We either
- * use a transparent background or a parent-relative background and ignore the
- * style background. So, just don't chain up.
- */
-}
-
-guint
-_gtk_tray_icon_send_message (GtkTrayIcon *icon,
- gint timeout,
- const gchar *message,
- gint len)
-{
- guint stamp;
- Display *xdisplay;
-
- g_return_val_if_fail (GTK_IS_TRAY_ICON (icon), 0);
- g_return_val_if_fail (timeout >= 0, 0);
- g_return_val_if_fail (message != NULL, 0);
-
- if (icon->priv->manager_window == None)
- return 0;
-
- if (len < 0)
- len = strlen (message);
-
- stamp = icon->priv->stamp++;
-
- /* Get ready to send the message */
- gtk_tray_icon_send_manager_message (icon, SYSTEM_TRAY_BEGIN_MESSAGE,
- (Window)gtk_plug_get_id (GTK_PLUG (icon)),
- timeout, len, stamp);
-
- /* Now to send the actual message */
- xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
- gdk_error_trap_push ();
- while (len > 0)
- {
- XClientMessageEvent ev;
-
- memset (&ev, 0, sizeof (ev));
- ev.type = ClientMessage;
- ev.window = (Window)gtk_plug_get_id (GTK_PLUG (icon));
- ev.format = 8;
- ev.message_type = XInternAtom (xdisplay,
- "_NET_SYSTEM_TRAY_MESSAGE_DATA", False);
- if (len > 20)
- {
- memcpy (&ev.data, message, 20);
- len -= 20;
- message += 20;
- }
- else
- {
- memcpy (&ev.data, message, len);
- len = 0;
- }
-
- XSendEvent (xdisplay,
- icon->priv->manager_window, False,
- StructureNotifyMask, (XEvent *)&ev);
- }
- gdk_error_trap_pop_ignored ();
-
- return stamp;
-}
-
-void
-_gtk_tray_icon_cancel_message (GtkTrayIcon *icon,
- guint id)
-{
- g_return_if_fail (GTK_IS_TRAY_ICON (icon));
- g_return_if_fail (id > 0);
-
- gtk_tray_icon_send_manager_message (icon, SYSTEM_TRAY_CANCEL_MESSAGE,
- (Window)gtk_plug_get_id (GTK_PLUG (icon)),
- id, 0, 0);
-}
-
-GtkTrayIcon *
-_gtk_tray_icon_new_for_screen (GdkScreen *screen,
- const gchar *name)
-{
- g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
-
- return g_object_new (GTK_TYPE_TRAY_ICON,
- "screen", screen,
- "title", name,
- NULL);
-}
-
-GtkTrayIcon*
-_gtk_tray_icon_new (const gchar *name)
-{
- return g_object_new (GTK_TYPE_TRAY_ICON,
- "title", name,
- NULL);
-}
-
-GtkOrientation
-_gtk_tray_icon_get_orientation (GtkTrayIcon *icon)
-{
- g_return_val_if_fail (GTK_IS_TRAY_ICON (icon), GTK_ORIENTATION_HORIZONTAL);
-
- return icon->priv->orientation;
-}
-
-gint
-_gtk_tray_icon_get_padding (GtkTrayIcon *icon)
-{
- g_return_val_if_fail (GTK_IS_TRAY_ICON (icon), 0);
-
- return icon->priv->padding;
-}
-
-gint
-_gtk_tray_icon_get_icon_size (GtkTrayIcon *icon)
-{
- g_return_val_if_fail (GTK_IS_TRAY_ICON (icon), 0);
-
- return icon->priv->icon_size;
-}
+++ /dev/null
-/* gtktrayicon.h
- * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __GTK_TRAY_ICON_H__
-#define __GTK_TRAY_ICON_H__
-
-#include "gtkplug.h"
-
-G_BEGIN_DECLS
-
-#define GTK_TYPE_TRAY_ICON (gtk_tray_icon_get_type ())
-#define GTK_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_TRAY_ICON, GtkTrayIcon))
-#define GTK_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_TRAY_ICON, GtkTrayIconClass))
-#define GTK_IS_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_TRAY_ICON))
-#define GTK_IS_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_TRAY_ICON))
-#define GTK_TRAY_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TRAY_ICON, GtkTrayIconClass))
-
-typedef struct _GtkTrayIcon GtkTrayIcon;
-typedef struct _GtkTrayIconPrivate GtkTrayIconPrivate;
-typedef struct _GtkTrayIconClass GtkTrayIconClass;
-
-struct _GtkTrayIcon
-{
- GtkPlug parent_instance;
-
- GtkTrayIconPrivate *priv;
-};
-
-struct _GtkTrayIconClass
-{
- GtkPlugClass parent_class;
-
- /* Padding for future expansion */
- void (*_gtk_reserved1);
- void (*_gtk_reserved2);
- void (*_gtk_reserved3);
- void (*_gtk_reserved4);
-};
-
-GDK_AVAILABLE_IN_ALL
-GType gtk_tray_icon_get_type (void) G_GNUC_CONST;
-
-GtkTrayIcon *_gtk_tray_icon_new_for_screen (GdkScreen *screen,
- const gchar *name);
-
-GtkTrayIcon *_gtk_tray_icon_new (const gchar *name);
-
-guint _gtk_tray_icon_send_message (GtkTrayIcon *icon,
- gint timeout,
- const gchar *message,
- gint len);
-void _gtk_tray_icon_cancel_message (GtkTrayIcon *icon,
- guint id);
-
-GtkOrientation _gtk_tray_icon_get_orientation (GtkTrayIcon *icon);
-gint _gtk_tray_icon_get_padding (GtkTrayIcon *icon);
-gint _gtk_tray_icon_get_icon_size (GtkTrayIcon *icon);
-
-G_END_DECLS
-
-#endif /* __GTK_TRAY_ICON_H__ */
* Mark McLoughlin <mark@skynet.ie>
*/
+#define GDK_DISABLE_DEPRECATION_WARNINGS
#include <gtk/gtk.h>
#include <stdlib.h>